# **📌 `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 色深格式。