diff --git a/README.md b/README.md index f00e2a1..d925e1d 100644 --- a/README.md +++ b/README.md @@ -76,13 +76,14 @@ Please note that this process assumes that you have CUDA SDK **11** installed, n ## Interactive Viewers Remote Viewer and Gaussian Viewer are integrated into one Viewer and it is driven by ```train.py``` or ```view.py```. We provide pre-built binaries for Windows [here](https://drive.google.com/file/d/1DRFrtFUfz27QvQKOWbYXbRS2o2eSgaUT/view?usp=sharing) for an efficient setup. -If your OS is Ubuntu 22.04, you need to compile the viewer locally: +If your OS is Ubuntu 24.04, you need to compile the viewer locally: ```shell # Dependencies -sudo apt install -y libglew-dev libassimp-dev libboost-all-dev libgtk-3-dev libopencv-dev libglfw3-dev libavdevice-dev libavcodec-dev libeigen3-dev libxxf86vm-dev libembree-dev +sudo apt install -y libglew-dev libassimp-dev libboost-all-dev libgtk-3-dev libopencv-dev libglfw3-dev libavdevice-dev libavcodec-dev libeigen3-dev libxxf86vm-dev +# download and unpack https://github.com/RenderKit/embree/releases/download/v3.13.5/embree-3.13.5.x86_64.linux.tar.gz # Project setup cd SIBR_viewers -cmake -Bbuild . -DCMAKE_BUILD_TYPE=Release # add -G Ninja to build faster +cmake -Bbuild . -DCMAKE_BUILD_TYPE=Release -Dembree_DIR:PATH=/path/to/embree-3.13.5.x86_64.linux/lib/cmake/embree-3.13.5/ # add -G Ninja to build faster cmake --build build -j24 --target install ``` diff --git a/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake b/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake deleted file mode 100644 index 0d07237..0000000 --- a/SIBR_viewers/cmake/linux/Modules/FindEmbree.cmake +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (C) 2020, Inria -# GRAPHDECO research group, https://team.inria.fr/graphdeco -# All rights reserved. -# -# This software is free for non-commercial, research and evaluation use -# under the terms of the LICENSE.md file. -# -# For inquiries contact sibr@inria.fr and/or George.Drettakis@inria.fr - -## Important Note: -## This is not an official Find*cmake. It has been written for searching through -## a custom path (EMBREE_DIR) before checking elsewhere. -## -## FindEMBREE.cmake -## Find EMBREE's includes and library -## -## This module defines : -## [in] EMBREE_DIR, The base directory to search for EMBREE (as cmake var or env var) -## [out] EMBREE_INCLUDE_DIR where to find EMBREE.h -## [out] EMBREE_LIBRARIES, EMBREE_LIBRARY, libraries to link against to use EMBREE -## [out] EMBREE_FOUND, If false, do not try to use EMBREE. -## - - -if(NOT EMBREE_DIR) - set(EMBREE_DIR "$ENV{EMBREE_DIR}" CACHE PATH "EMBREE root directory") -endif() -if(EMBREE_DIR) - file(TO_CMAKE_PATH ${EMBREE_DIR} EMBREE_DIR) -endif() - - -## set the LIB POSTFIX to find in a right directory according to what kind of compiler we use (32/64bits) -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(EMBREE_SEARCH_LIB "lib64") - set(EMBREE_SEARCH_BIN "bin64") - set(EMBREE_SEARCH_LIB_PATHSUFFIXE "x64") -else() - set(EMBREE_SEARCH_LIB "lib32") - set(EMBREE_SEARCH_BIN "bin32") - set(EMBREE_SEARCH_LIB_PATHSUFFIXE "x86") -endif() - -set(PROGRAMFILESx86 "PROGRAMFILES(x86)") - -FIND_PATH(EMBREE_INCLUDE_DIR - NAMES embree3/rtcore_geometry.h - PATHS - ${EMBREE_DIR} - ## linux - /usr - /usr/local - /opt/local - ## windows - "$ENV{PROGRAMFILES}/EMBREE" - "$ENV{${PROGRAMFILESx86}}/EMBREE" - "$ENV{ProgramW6432}/EMBREE" - PATH_SUFFIXES include -) - -FIND_LIBRARY(EMBREE_LIBRARY - NAMES embree3 - PATHS - ${EMBREE_DIR}/${EMBREE_SEARCH_LIB} - ${EMBREE_DIR}/lib - ## linux - /usr/${EMBREE_SEARCH_LIB} - /usr/local/${EMBREE_SEARCH_LIB} - /opt/local/${EMBREE_SEARCH_LIB} - /usr/lib - /usr/local/lib - /opt/local/lib - ## windows - "$ENV{PROGRAMFILES}/EMBREE/${EMBREE_SEARCH_LIB}" - "$ENV{${PROGRAMFILESx86}}/EMBREE/${EMBREE_SEARCH_LIB}" - "$ENV{ProgramW6432}/EMBREE/${EMBREE_SEARCH_LIB}" - "$ENV{PROGRAMFILES}/EMBREE/lib" - "$ENV{${PROGRAMFILESx86}}/EMBREE/lib" - "$ENV{ProgramW6432}/EMBREE/lib" - PATH_SUFFIXES ${EMBREE_SEARCH_LIB_PATHSUFFIXE} -) -set(EMBREE_LIBRARIES ${EMBREE_LIBRARY}) - -MARK_AS_ADVANCED(EMBREE_INCLUDE_DIR EMBREE_LIBRARIES) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(EMBREE - REQUIRED_VARS EMBREE_INCLUDE_DIR EMBREE_LIBRARIES - FAIL_MESSAGE "EMBREE wasn't found correctly. Set EMBREE_DIR to the root SDK installation directory." -) - -if(NOT EMBREE_FOUND) - set(EMBREE_DIR "" CACHE STRING "Path to EMBREE install directory") -endif() diff --git a/SIBR_viewers/cmake/linux/dependencies.cmake b/SIBR_viewers/cmake/linux/dependencies.cmake index a7854bb..ffefd6b 100644 --- a/SIBR_viewers/cmake/linux/dependencies.cmake +++ b/SIBR_viewers/cmake/linux/dependencies.cmake @@ -124,7 +124,13 @@ sibr_addlibrary( # CLUSTER #find_package(embree 3.0 REQUIRED PATHS "/data/graphdeco/share/embree/usr/local/lib64/cmake/" ) -find_package(embree 3.0 ) +find_package(embree REQUIRED ) + +if(embree_VERSION VERSION_GREATER_EQUAL 3.0 AND embree_VERSION VERSION_LESS 4.0) + # embree is in the 3.x range +else() + message(FATAL_ERROR "Only Embree 3.x versions are supported.") +endif() ################### ## Find eigen3 diff --git a/SIBR_viewers/src/core/raycaster/CMakeLists.txt b/SIBR_viewers/src/core/raycaster/CMakeLists.txt index 91d6047..22c78af 100644 --- a/SIBR_viewers/src/core/raycaster/CMakeLists.txt +++ b/SIBR_viewers/src/core/raycaster/CMakeLists.txt @@ -23,7 +23,7 @@ include_directories( if(WIN32) target_link_libraries(${PROJECT_NAME} OpenMP::OpenMP_CXX - embree3 + embree sibr_graphics sibr_assets nanoflann diff --git a/SIBR_viewers/src/core/video/FFmpegVideoEncoder.cpp b/SIBR_viewers/src/core/video/FFmpegVideoEncoder.cpp index d908531..f41a5c6 100644 --- a/SIBR_viewers/src/core/video/FFmpegVideoEncoder.cpp +++ b/SIBR_viewers/src/core/video/FFmpegVideoEncoder.cpp @@ -43,11 +43,11 @@ namespace sibr { SIBR_LOG << "[FFMPEG] Registering all." << std::endl; // Ignore next line warning. #pragma warning(suppress : 4996) - av_register_all(); - ffmpegInitDone = true; - } - - sibr::Vector2i sizeFix = size; + // av_register_all(); + ffmpegInitDone = true; + } + + sibr::Vector2i sizeFix = size; bool hadToFix = false; if(sizeFix[0]%2 != 0) { sizeFix[0] -= 1; @@ -79,10 +79,17 @@ namespace sibr { } if (video_st) { - avcodec_close(video_st->codec); - av_free(frameYUV); - } - avio_close(pFormatCtx->pb); + AVCodecContext* codec_ctx = avcodec_alloc_context3(nullptr); + if (codec_ctx) { + // Initialize codec context with parameters from the stream + avcodec_parameters_to_context(codec_ctx, video_st->codecpar); + + // Close the codec context if it's already opened + avcodec_free_context(&codec_ctx); // This frees the codec context + } + av_free(frameYUV); + } + avio_close(pFormatCtx->pb); avformat_free_context(pFormatCtx); needFree = false; @@ -136,10 +143,15 @@ namespace sibr { return; } - pCodecCtx = video_st->codec; - pCodecCtx->codec_id = fmt->video_codec; - pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; - pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; + pCodecCtx = avcodec_alloc_context3(NULL); // Allocate a new codec context + if (!pCodecCtx) { + SIBR_WRG << "[FFMPEG] Could not allocate codec context" << std::endl; + return; + } + + pCodecCtx->codec_id = fmt->video_codec; + pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; + pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; pCodecCtx->width = w; pCodecCtx->height = h; pCodecCtx->gop_size = 10; @@ -163,27 +175,50 @@ namespace sibr { int res = avcodec_open2(pCodecCtx, pCodec, ¶m); if(res < 0){ SIBR_WRG << "[FFMPEG] Failed to open encoder, error: " << res << std::endl; - return; - } - // Write the file header. + av_dict_free(¶m); + return; + } + // Write the file header. avformat_write_header(pFormatCtx, NULL); - // Prepare the scratch frame. - frameYUV = av_frame_alloc(); - frameYUV->format = (int)pCodecCtx->pix_fmt; - frameYUV->width = w; - frameYUV->height = h; - frameYUV->linesize[0] = w; - frameYUV->linesize[1] = w / 2; - frameYUV->linesize[2] = w / 2; - - yuSize[0] = frameYUV->linesize[0] * h; - yuSize[1] = frameYUV->linesize[1] * h / 2; - - pkt = av_packet_alloc(); - - initWasFine = true; - needFree = true; + // Prepare the scratch frame + frameYUV = av_frame_alloc(); + if (!frameYUV) { + SIBR_WRG << "[FFMPEG] Could not allocate frame" << std::endl; + avcodec_free_context(&pCodecCtx); // Free codec context on failure + return; + } + frameYUV->format = pCodecCtx->pix_fmt; + frameYUV->width = w; + frameYUV->height = h; + + // Allocate buffer for the frame + int ret = av_frame_get_buffer(frameYUV, 32); // Allocate buffer for the frame + if (ret < 0) { + SIBR_WRG << "[FFMPEG] Could not allocate frame data" << std::endl; + av_frame_free(&frameYUV); // Free frame on failure + avcodec_free_context(&pCodecCtx); // Free codec context on failure + return; + } + + // Calculate sizes + yuSize[0] = frameYUV->linesize[0] * h; + yuSize[1] = frameYUV->linesize[1] * h / 2; + + // Allocate packet + pkt = av_packet_alloc(); + if (!pkt) { + SIBR_WRG << "[FFMPEG] Could not allocate packet" << std::endl; + av_frame_free(&frameYUV); // Free frame on failure + avcodec_free_context(&pCodecCtx); // Free codec context on failure + return; + } + + initWasFine = true; + needFree = true; + + // Cleanup: Free the parameter dictionary + av_dict_free(¶m); #endif } @@ -227,23 +262,38 @@ namespace sibr { } #ifndef HEADLESS - bool FFVideoEncoder::encode(AVFrame * frame) - { - int got_picture = 0; - - int ret = avcodec_encode_video2(pCodecCtx, pkt, frameYUV, &got_picture); - if (ret < 0) { - SIBR_WRG << "[FFMPEG] Failed to encode frame." << std::endl; - return false; - } - if (got_picture == 1) { - pkt->stream_index = video_st->index; - ret = av_write_frame(pFormatCtx, pkt); - av_packet_unref(pkt); - } - - return true; - } + bool FFVideoEncoder::encode(AVFrame* frame) + { + // Send the frame for encoding + int ret = avcodec_send_frame(pCodecCtx, frame); + if (ret < 0) { + SIBR_WRG << "[FFMPEG] Failed to send frame for encoding, error: " << ret << std::endl; + return false; + } + + // Receive the encoded packet + ret = avcodec_receive_packet(pCodecCtx, pkt); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + // Not enough data to encode, or end of stream reached + return true; + } + SIBR_WRG << "[FFMPEG] Failed to receive packet, error: " << ret << std::endl; + return false; + } + + // Set the stream index and write the packet + pkt->stream_index = video_st->index; + ret = av_write_frame(pFormatCtx, pkt); + if (ret < 0) { + SIBR_WRG << "[FFMPEG] Failed to write frame, error: " << ret << std::endl; + return false; + } + + // Unreference the packet + av_packet_unref(pkt); + return true; + } #endif } diff --git a/SIBR_viewers/src/core/video/FFmpegVideoEncoder.hpp b/SIBR_viewers/src/core/video/FFmpegVideoEncoder.hpp index 18f92a1..b165450 100644 --- a/SIBR_viewers/src/core/video/FFmpegVideoEncoder.hpp +++ b/SIBR_viewers/src/core/video/FFmpegVideoEncoder.hpp @@ -104,11 +104,11 @@ namespace sibr { #ifndef HEADLESS AVFormatContext* pFormatCtx; ///< Format context. - AVOutputFormat* fmt; ///< Output format. - AVStream* video_st; ///< Output stream. - AVCodecContext* pCodecCtx; ///< Codec context. - AVCodec* pCodec; ///< Codec. - AVPacket * pkt; ///< Encoding packet. + const AVOutputFormat* fmt; ///< Output format. + AVStream* video_st; ///< Output stream. + AVCodecContext* pCodecCtx; ///< Codec context. + const AVCodec* pCodec; ///< Codec. + AVPacket * pkt; ///< Encoding packet. #endif static bool ffmpegInitDone; ///< FFMPEG initialization status. diff --git a/SIBR_viewers/src/core/video/VideoUtils.hpp b/SIBR_viewers/src/core/video/VideoUtils.hpp index e79dac1..bae79d8 100644 --- a/SIBR_viewers/src/core/video/VideoUtils.hpp +++ b/SIBR_viewers/src/core/video/VideoUtils.hpp @@ -935,18 +935,18 @@ namespace sibr { } } - uint getModeIndice() const { - uint mode, mode_size = 0; - for (const auto & [key, val] : bins) { - if (val > mode_size) { - mode_size = val; - mode = key; - } - } - return mode; - } - - T getBinMiddle(uint bin) const { + // uint getModeIndice() const { + // uint mode, mode_size = 0; + // for (const auto & [key, val] : bins) { + // if (val > mode_size) { + // mode_size = val; + // mode = key; + // } + // } + // return mode; + // } + + T getBinMiddle(uint bin) const { return static_cast(min + bin_range * (bin + 0.5)); } diff --git a/SIBR_viewers/src/core/view/InteractiveCameraHandler.cpp b/SIBR_viewers/src/core/view/InteractiveCameraHandler.cpp index dbb3cca..86beab1 100644 --- a/SIBR_viewers/src/core/view/InteractiveCameraHandler.cpp +++ b/SIBR_viewers/src/core/view/InteractiveCameraHandler.cpp @@ -26,10 +26,10 @@ namespace sibr { InteractiveCameraHandler::InteractiveCameraHandler(const bool supportRecording) : _trackball(true) { - _currentMode = FPS; - _shouldSmooth = IBRVIEW_USESMOOTHCAM; - _startCam = 0; - _interpFactor = 0; + _currentMode = TRACKBALL; + _shouldSmooth = IBRVIEW_USESMOOTHCAM; + _startCam = 0; + _interpFactor = 0; _shouldSnap = false; _supportRecording = supportRecording; _radius = 100.0f;