視訊轉碼後有色差要如何處理呢?丨有問有答
今天我們要討論的是 關鍵幀的音視訊開發圈 的一位朋友在社群裡提的問題,如下:
遇到了視訊轉碼後有色差,這種一般如何處理呢?
以下是回答,歡迎大家留言討論補充:
1、色差是如何產生的?
1)有失真壓縮產生的質量損失。
-
解決方法為儘可能的提高位元速率。
-
可以使用 FFmpeg 指令檢視原位元速率與輸出位元速率對比,如果使用硬體編碼位元速率要高於原位元速率一些,因為原檔案可能使用了更高階的編碼方式(軟體編碼)或編碼引數(HEVC)。
2)顏色空間轉換產生的損失。
-
解決方法為儘量避免顏色空間的轉換,如果必須轉換需要找到正確的顏色轉換矩陣。
-
可以使用 FFmpeg 指令對比色差檔案與原檔案
color_range
、color_space
。
$ ffprobe -show_streams -i test.mp4
2、如何做顏色空間轉換?
顏色空間轉換每個模組都會有所涉及,播放器、轉碼、獲取縮圖等,但按照底層模組劃分如下:
1)解碼模組:需要獲取出正確的 ColorSpace
、 ColorRange
,然後傳遞給後面的模組。
-
CVPixelBuffer CVImageBufferYCbCrMatrix FullRange CVPixelBufferGetPixelFormatType(buffer) == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
-
MediaFormat KEY_COLOR_STANDARD KEY_COLOR_RANGE
-
FFmpeg 模組需要根據解碼後資料 AVFrame 獲取,ColorSpace 為
colorspace
,ColorRange 為color_range
。
2)編碼模組:根據外層輸入的 ColorSpace
、 ColorRange
,設定給編碼器即可。
-
iOS VideoToolBox 編碼設定與解碼相對應
kVTCompressionPropertyKey_YCbCrMatrix
。 -
Android 編碼設定與解碼相對應
KEY_COLOR_STANDARD
、KEY_COLOR_RANGE
。 -
FFmpeg X264 編碼設定 x264_param_t 內
vui.b_fullrange
、vui.i_colmatrix
。
3)YUV 資料轉換 RGBA 紋理模組。
-
資料轉紋理主要涉及 GL 矩陣操作,根據解碼後的 ColorSpace 與 ColorRange 生成合適的矩陣。
-
GPUImage 矩陣生成,參考: GPUImage [1] 。
-
libyuv 矩陣生成(搜尋 『bt.』),參考: libyuv [2] 。
4)RGBA 紋理轉換 YUV 資料模組。
-
紋理轉資料與資料轉紋理相反的流程,但具體轉換為哪種 ColorSpace 與 ColorRange 都可以的。
-
參考 RGBA 轉 YUV 即可: RGB2YUV [3] 。
5)RGB 資料與 YUV 資料轉換模組。
-
libyuv I420ToARGBMatrix YuvConstants
3、其他建議
1)儘量減少自定義處理顏色空間轉換。
Android 平臺儘量使用 Surface 解碼與編碼,好處就是不需要手動處理。
2)ByteBuffer 編碼必須設定 ColorSpace
、 ColorRange
。
如果不設定底層不清楚輸入進來的資料顏色格式,只能根據預設值隨意發揮了。
3) ColorSpace
、 ColorRange
預設值。
-
本地檔案
ColorSpace
為空,則直接預設為601
即可。 -
本地檔案
ColorRange
為空,則直接預設為非FullRange
。
如果你也對音視訊技術感興趣,比如,符合下面的情況:
-
在校大學生 → 學習音視訊開發
-
iOS/Android 客戶端開發 → 轉入音視訊領域
-
直播/短視訊業務開發 → 深入音視訊底層 SDK 開發
-
音視訊 SDK 開發 → 提升技能,解決優化瓶頸
可以長按識別或掃描下面二維碼,瞭解一下這個社群,根據自己的情況按需加入:
參考資料
CPUImage: http://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageColorConversion.m
libyuv: http://github.com/lemenkov/libyuv/blob/master/source/row_common.cc
RGB2YUV: http://en.wikipedia.org/wiki/YUV#Y%E2%80%B2UV444_to_RGB888_conversion
- 一文看完 WWDC 2022 音視訊相關的更新要點丨音視訊工程示例
- 一看就懂的 OpenGL 基礎概念丨音視訊基礎
- 視訊轉碼後有色差要如何處理呢?丨有問有答
- WWDC 2022 音視訊相關 Session 概覽(EDR 相關)丨音視訊工程示例
- 音視訊知識圖譜 2022.06
- Android AVDemo(13):視訊渲染丨音視訊工程示例
- 想在自己的視訊平臺支援 HDR 需要做哪些工作?丨有問有答
- Android AVDemo(11):視訊轉封裝,從 MP4 到 MP4丨音視訊工程示例
- 音視訊面試題集錦 2022.05
- Android AVDemo(6):音訊渲染,免費獲得原始碼丨音視訊工程示例
- Android AVDemo(4):音訊解封裝,從 MP4 中解封裝出 AAC丨音視訊工程示例
- 如何根據 NALU 裸流資料來判斷其是 H.264 還是 H.265 編碼?丨有問有答
- 音視訊知識圖譜 2022.04
- Android AVDemo(2):音訊編碼,採集 PCM 資料編碼為 AAC丨音視訊工程示例
- 音視訊面試題集錦 2022.04
- Android AVDemo(1):音訊採集,免費獲取全部原始碼丨音視訊工程示例
- iOS 視訊處理框架及重點 API 合集丨音視訊工程示例
- iOS AVDemo(13):視訊渲染,用 Metal 渲染丨音視訊工程示例
- 如何像抖音直播一樣,從 App 直播間到桌面畫中畫實現畫面無縫切換?丨有問有答
- 如何在視訊採集流水線中增加濾鏡處理節點?丨有問有答