# **📌 `PCCJMLibVideoEncoderImpl.cpp` 解析** ### File Location: `source\lib\PccLibVideoEncoder\source\PCCJMLibVideoEncoderImpl.cpp` ## Author: 品為 WIll Chu 這段程式碼是 **ITRI 對 H.264(AVC)JM 參考編碼器** 進行的客製化修改,使其能夠作為 **TMC2(點雲壓縮)** 的內部編碼函式庫 (`JMLIB`)。 ### **🔹 關鍵目的** - **將 JM 參考編碼器整合到 TMC2** 作為 **內部視訊編碼器**,支援點雲壓縮 (PCC) 的視訊編碼。 - **使用 JM 參考編碼器進行 H.264 編碼**,並且與 PCC 視訊數據 (`PCCVideo`) 進行對接。 - **初始化編碼器、執行視訊編碼、輸出位元流**,並清除暫存檔案。 --- ## **🔹 程式架構** 📂 `PCCJMLibVideoEncoderImpl.cpp` 主要分為 **三大部分**: 1. **引入標頭與函式宣告**(包含 JM 內部函式) 2. **`PCCJMLibVideoEncoderImpl` 類別的實作** 3. **模板實例化**(支援 `uint8_t` 和 `uint16_t`) --- ## **🔹 1. 引入標頭與函式宣告** ```cpp #include "PCCCommon.h" #ifdef USE_JMLIB_VIDEO_CODEC #include "PCCJMLibVideoEncoderImpl.h" extern "C" { #include "mbuffer.h" #include "global.h" ``` ### 📌功能 - **`#ifdef USE_JMLIB_VIDEO_CODEC`:只有啟用 JMLIB 編碼器時才會編譯這個檔案。** - **`extern "C"`確保 C++ 程式可以呼叫 JM 參考編碼器(用 C 語言寫成的函式庫)。** ### **🔑 引入的 C 語言函式(來自 JM)** - **`alloc_encoder()`:分配編碼器記憶體** - **`init_encoder()`:初始化 H.264/AVC 編碼器** - **`encode_sequence()`:執行整個視訊編碼流程** - **`free_encoder()`:釋放編碼器記憶體** - **`Configure()`:載入 H.264/AVC 編碼參數** - **`img2buf()`:將影像數據轉換為緩衝區格式** ## **🔹 2. PCCJMLibVideoEncoderImpl 類別** 這個類別是 用來控制 JM 參考編碼器的 C++ 介面,用於點雲壓縮的視訊處理。 ### **🔹 類別建構與解構** ```cpp= template <typename T> PCCJMLibVideoEncoderImpl<T>::PCCJMLibVideoEncoderImpl() {} template <typename T> PCCJMLibVideoEncoderImpl<T>::~PCCJMLibVideoEncoderImpl() {} ``` - **模板類別:`PCCJMLibVideoEncoderImpl<T>` 支援 uint8_t 和 uint16_t(對應 8-bit 和 10-bit YUV)。** - **建構函式/解構函式:目前沒有額外操作,僅是空函式。** ### **🔹 `encode()` 函式** ```cpp= template <typename T> void PCCJMLibVideoEncoderImpl<T>::encode( PCCVideo<T, 3>& videoSrc, std::string arguments, PCCVideoBitstream& bitstream, PCCVideo<T, 3>& videoRec ) ``` 這是 核心函式,負責將 點雲視訊 (`videoSrc`) 壓縮為 H.264 (`bitstream`),並回傳 重建影像 (`videoRec`)。 ### **📌 (1) 解析參數** ```cpp= std::istringstream iss( arguments ); std::string token; std::vector<char*> args; while ( iss >> token ) { char* arg = new char[token.size() + 1]; copy( token.begin(), token.end(), arg ); arg[token.size()] = '\0'; args.push_back( arg ); } int argc = args.size(); char** argv = &args[0]; ``` --- ### 📌功能 - 解析 `arguments`(字串格式的編碼參數)。 - 轉換為 `argc/argv` 格式(類似 C 語言 `main(int argc, char** argv)` 參數)。 - `args.push_back(arg)` 儲存解析後的參數。 ### **📌 (2) 設定視訊格式** ```cpp= const size_t srcWidth = videoSrc.getWidth(); const size_t srcHeight = videoSrc.getHeight(); int32_t sourceBitDepthLuma = std::stoi( getParameter( arguments, "SourceBitDepthLuma=" ) ); PCCCOLORFORMAT format = videoSrc.getColorFormat(); const size_t nbyte = sourceBitDepthLuma == 10 ? 2 : 1; ``` ### 📌功能 - 取得 輸入影像寬 (`srcWidth`)、高 (`srcHeight`)。 - 從 arguments 讀取 亮度位元深度 (`SourceBitDepthLuma`),確定 8-bit (`1 byte`) 或 10-bit (`2 bytes`)。 - 取得影像色彩格式 (`format`)。 ----- ### **📌 (3) 初始化與編碼** ```cpp= alloc_encoder( &p_Enc ); Configure( p_Enc->p_Vid, p_Enc->p_Inp, argc, argv ); for ( size_t i = 0; i < args.size(); i++ ) { delete[] args[i]; } ``` ### 📌功能 - 分配 H.264 編碼器記憶體 (alloc_encoder()) - 設定 H.264 編碼參數 (Configure()) - 釋放 args 記憶體(避免記憶體洩漏) --- ### **📌 (4) 執行 H.264/AVC 編碼** ```cpp= // init encoder init_encoder( p_Enc->p_Vid, p_Enc->p_Inp ); // encode sequence encode_sequence( p_Enc->p_Vid, p_Enc->p_Inp ); // terminate sequence free_encoder_memory( p_Enc->p_Vid, p_Enc->p_Inp ); free_params( p_Enc->p_Inp ); free_encoder( p_Enc ); ``` ### 📌功能 - 初始化 H.264/AVC 編碼器 (init_encoder())。 - 執行編碼 (encode_sequence())。 - 釋放記憶體 (free_encoder_memory(), free_params(), free_encoder())。 - ---- ### **📌 (5) 儲存與清理** ```cpp= videoRec.clear(); videoRec.read( recName, srcWidth, srcHeight, format, nbyte ); bitstream.read( binName ); // Remove temp files removeFile( srcName ); removeFile( recName ); removeFile( binName ); ``` ### 📌功能 - 讀取重建影像 (videoRec.read())。 - 讀取 H.264 位元流 (bitstream.read())。 - 刪除暫存檔案 (removeFile())。 ## **🔹 3. 模板實例化** ```ccp= template class pcc::PCCJMLibVideoEncoderImpl<uint8_t>; template class pcc::PCCJMLibVideoEncoderImpl<uint16_t>; ``` 這裡 明確實例化 8-bit (uint8_t) 與 10-bit (uint16_t) 版本的 PCCJMLibVideoEncoderImpl。 ## 📌 總結 1. 這段程式碼是為了讓 JM(H.264 參考編碼器)能整合到 TMC2,用於點雲壓縮。 2. 負責 H.264 視訊編碼,包括初始化、參數設定、影像處理、編碼、釋放記憶體。 3. 支援 8-bit 與 10-bit 色深格式。