完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第57章 STM32H7硬件JPEG編解碼基礎知識和HAL庫API
本章節爲大家講解硬件JPEG,實際項目用到圖像顯示的地方比較多,有了硬件JPEG可以大大加速JPEG圖片顯示速度。
目錄
第57章 STM32H7硬件JPEG編解碼基礎知識和HAL庫API
57.3.2 JPEG的編解碼參數結構體JPEG_ConfTypeDef
57.3.3 JPEG結構體句柄JPEG_HandleTypeDef
57.4.4 函數HAL_JPEG_ConfigInputBuffer
57.4.5 函數HAL_JPEG_ConfigOutputBuffer
57.1 初學者重要提示
- 由於硬件JPEG解碼後輸出的圖像格式是YCbCr,所以本章對YCbCr進行了重點介紹。
- 測試STM32H7硬件JPEG解碼800*480圖片性能,全部通過SDRAM緩存數據,解碼10ms,顯示9ms:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93598 。
- JPEG涉及到的知識點還是比較多的,如果想深入瞭解JPEG的話,可以看本章2.6小節給的參考資料。
- 本章JPEG相關概念的介紹參考了wiki百科和百度百科。
57.2 硬件JPEG基礎知識
對於STM32H7的硬件JPEG瞭解到以下幾點即可:
- 支持JPEG解碼和編碼。
- 對每個像素數據進行編解碼只需一個時鐘週期。
- 支持RGB、 YCbCr、YCMK和BW(灰度)圖像色彩模型。
- 編解碼時每圖像分量8位深度。
57.2.1 JPEG硬件框圖
認識一個外設,最好的方式就是看它的框圖,方便我們快速地瞭解JPEG的基本功能,然後再看手冊瞭解細節。框圖如下所示:
通過這個框圖,我們可以得到如下信息:
- JPEG硬件外設支持編碼和解碼
並且對於輸入數據和輸出數據都有FIFO支持。
- jpeg_hclk
爲JPEG內核和寄存器提供時鐘。
- jpeg_it
JPEG全局中斷輸出。
- jpeg_ift_trg
JPEG輸入FIFO閾值信號,可觸發MDMA。
- jpeg_ifnf_trg
JPEG輸入FIFO未滿信號,可觸發MDMA。
- jpeg_oft_trg
JPEG輸出FIFO閥值信號,可觸發MDMA。
- jpeg_ofne_trg
JPEG輸出FIFO非空信號,可觸發MDMA。
- jpeg_oec_trg
JPEG轉換結束信號,可觸發MDMA。
57.2.2 YCbCr顏色格式
(注,硬件JPEG解碼後輸出的圖像格式是YCbCr,所以有必要了解下)
正如幾何上用座標空間來描述座標集,而色彩空間用數學方式來描述顏色集。常見的3種色彩模型是RGB,CMYK和YUV。
YCbCr是YUV經過縮放和修改的翻版,只是在表示方法上不同。其中Y是指亮度分量,Cb指藍色色度分量,而Cr指紅色色度分量。人眼對視頻的Y分量更敏感,因此通過對色度分量進行子採樣來減少色度分量後,人眼察覺不到的圖像質量的變化。
在YUV 家族中,YCbCr 是在計算機系統中應用最多的成員,其應用領域廣泛,JPEG、MPEG均採用此格式。一般人們所講的YUV大多是指YCbCr。
57.2.3 YCbCr採樣格式
YCbCr有許多取樣格式,如YCbCr 4:4:4,YCbCr 4:2:2,YCbCr 4:1:1 和YCbCr 4:2:0。
- 4:2:0
表示每4個像素有4個亮度分量,2個色度分量 (YYYYCbCr),僅採樣奇數掃描線,是便攜式視頻設備(MPEG-4)以及電視會議(H.263)最常用格式。
- 4:2:2
表示每4個像素有4個亮度分量,4個色度分量(YYYYCbCrCbCr),是DVD、數字電視、HDTV以及其它消費類視頻設備的最常用格式。
- 4:4:4
表示全像素點陣(YYYYCbCrCbCrCbCrCbCr),用於高質量視頻應用、演播室以及專業視頻產品。
具體的採樣方式如下圖所示,以8個像素爲一個單元進行採樣:
由上面的截圖可以瞭解到:
4:4:4表示Y通道,Cb+Cr通道全部採樣。
4:2:2表示Y通道全部採樣,而Cb+Cr通道兩個像素爲一組,統一採用第1個顏色值。
4:2:0表示Y通道全部採樣,而Cb+Cr通道四個像素爲一組,統一採用第1個顏色值。
下面是整體效果,方便大家更好的理解:
57.2.4 YCbCr的優勢
RGB信號作爲存儲和傳輸的效率不高,因爲它們具有大量冗餘信息。而使用YCbCr可以丟棄一些信息以減少帶寬,因爲人的肉眼對視頻的Y分量更敏感,因此通過對色度分量進行子採樣來減少色度分量後,肉眼察覺不到的圖像質量的變化。瞭解這種人爲缺點,NTSC和PAL等標準大大降低了色度通道的帶寬。
57.2.5 YCbCr和RGB互轉
爲了方便大家更好的瞭解YCbCr和RGB圖像的實際效果,特此蒐集整理了兩個截圖(來自WIKI百科)。下面是圖像轉YCBCR的效果:四個圖,從上到下依次是原始圖像,Y通道,Cb通道和Cr通道。
下面是一幅圖像分別以R,G,B通道和Y,CB,CR通道的方式展示:
57.2.6 JPEG編解碼知識
JPEG涉及到的知識點比較多,這裏有之前整理的20多個專題知識點,大家有興趣可以瞭解下(不瞭解也沒有關係,不影響使用硬件JPEG外設):
http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=71 。
另外還ST整理的JPEG應用筆記,含中文版:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=93516 。
57.3 硬件JPEG的HAL庫用法
JPEG的HAL庫用法其實就是幾個結構體變量成員的配置和使用,然後配置時鐘,並根據需要配置NVIC、中斷和MDMA。下面我們逐一展開爲大家做個說明。
57.3.1 JPEG寄存器結構體JPEG_TypeDef
JPEG相關的寄存器是通過HAL庫中的結構體JPEG_TypeDef定義的,在stm32h743xx.h中可以找到它們的具體定義:
typedef struct { __IO uint32_t CONFR0; __IO uint32_t CONFR1; __IO uint32_t CONFR2; __IO uint32_t CONFR3; __IO uint32_t CONFR4; __IO uint32_t CONFR5; __IO uint32_t CONFR6; __IO uint32_t CONFR7; uint32_t Reserved20[4]; __IO uint32_t CR; __IO uint32_t SR; __IO uint32_t CFR; uint32_t Reserved3c; __IO uint32_t DIR; __IO uint32_t DOR; uint32_t Reserved48[2]; __IO uint32_t QMEM0[16]; __IO uint32_t QMEM1[16]; __IO uint32_t QMEM2[16]; __IO uint32_t QMEM3[16]; __IO uint32_t HUFFMIN[16]; __IO uint32_t HUFFBASE[32]; __IO uint32_t HUFFSYMB[84]; __IO uint32_t DHTMEM[103]; uint32_t Reserved4FC; __IO uint32_t HUFFENC_AC0[88]; __IO uint32_t HUFFENC_AC1[88]; __IO uint32_t HUFFENC_DC0[8]; __IO uint32_t HUFFENC_DC1[8]; } JPEG_TypeDef;
__IO表示volatile, 這是標準C語言中的一個修飾字,表示這個變量是非易失性的,編譯器不要將其優化掉。core_m7.h 文件定義了這個宏:
#define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */
下面我們再看JPEG的定義,在stm32h743xx.h文件。
#define PERIPH_BASE ((uint32_t)0x40000000) #define D1_AHB1PERIPH_BASE (PERIPH_BASE + 0x12000000) #define JPEG ((JPEG_TypeDef *) JPGDEC_BASE) #define JPGDEC_BASE (D1_AHB1PERIPH_BASE + 0x3000) <----- 展開這個宏,(JPEG_TypeDef *) 0x52003000
我們訪問JPEG的CR寄存器可以採用這種形式:JPEG->CR = 0。
57.3.2 JPEG的編解碼參數結構體JPEG_ConfTypeDef
此結構體用於JPEG的編解碼參數,具體定義如下:
typedef struct { uint8_t ColorSpace; uint8_t ChromaSubsampling; uint32_t ImageHeight; uint32_t ImageWidth; uint8_t ImageQuality; }JPEG_ConfTypeDef;
下面將這幾個參數逐一爲大家做個說明:
- uint8_t ColorSpace
此參數用於設置輸出數據流中的量化表,具體支持的參數如下:
#define JPEG_GRAYSCALE_COLORSPACE ((uint32_t)0x00000000U) /* 灰度(1 個量化表)*/ #define JPEG_YCBCR_COLORSPACE JPEG_CONFR1_COLORSPACE_0 /* YUV(2 個量化表) */ #define JPEG_CMYK_COLORSPACE JPEG_CONFR1_COLORSPACE /* CMYK(4 個量化表)*/
- uint8_t ChromaSubsampling
此參數用於色度子採樣,具體支持的參數如下:
#define JPEG_444_SUBSAMPLING ((uint32_t)0x00000000U) /* 4:4:4 */ #define JPEG_420_SUBSAMPLING ((uint32_t)0x00000001U) /* 4:2:0 */ #define JPEG_422_SUBSAMPLING ((uint32_t)0x00000002U) /* 4:2:2 */
- uint32_t ImageHeight
此參數用於圖像高度。
- uint32_t ImageWidth
此參數用於圖像寬度。
- uint8_t ImageQuality
此參數用於圖像質量,參數範圍1 – 100,1最差,100最好。
57.3.3 JPEG結構體句柄JPEG_HandleTypeDef
HAL庫在JPEG_TypeDef, JPEG_ConfTypeDef的基礎上封裝了一個結構體JPEG_HandleTypeDef,定義如下:
typedef struct { JPEG_TypeDef *Instance; JPEG_ConfTypeDef Conf; uint8_t *pJpegInBuffPtr; uint8_t *pJpegOutBuffPtr; __IO uint32_t JpegInCount; __IO uint32_t JpegOutCount; uint32_t InDataLength; uint32_t OutDataLength; MDMA_HandleTypeDef *hdmain; MDMA_HandleTypeDef *hdmaout; uint8_t CustomQuanTable; uint8_t *QuantTable0; uint8_t *QuantTable1; uint8_t *QuantTable2; uint8_t *QuantTable3; HAL_LockTypeDef Lock; __IO HAL_JPEG_STATETypeDef State; __IO uint32_t ErrorCode; __IO uint32_t Context; }JPEG_HandleTypeDef;
下面將這幾個參數逐一做個說明。
- JPEG_TypeDef *Instance
這個參數是寄存器的例化,方便操作寄存器,詳見本章3.1小節。
- JPEG_ConfTypeDef Conf
這個參數是用戶接觸較多的,用於JPEG的編解碼參數,詳見本章3.2小節。
- uint8_t *pJpegInBuffPtr
JPEG編解碼輸入緩衝地址
- uint8_t *pJpegOutBuffPtr
JPEG編解碼輸出緩衝地址
- __IO uint32_t JpegInCount
JPEG內部輸入計數。
- __IO uint32_t JpegOutCount
JPEG內部輸出計數。
- uint32_t InDataLength
JPEG輸入緩衝區長度,單位字節
- uint32_t OutDataLength
JPEG輸出緩衝區長度,單位字節。
- MDMA_HandleTypeDef *hdmain
- MDMA_HandleTypeDef *hdmaout
MDMA句柄結構體指針變量,用於關聯JPEG句柄,方便調用。
- uint8_t CustomQuanTable
如果此參數設置爲1,將使用用戶設置的量化表。
- uint8_t *QuantTable0;
- uint8_t *QuantTable1;
- uint8_t *QuantTable2;
- uint8_t *QuantTable3;
指定量化表地址。
- HAL_LockTypeDef Lock
- __IO HAL_JPEG_STATETypeDef State
- __IO uint32_t ErrorCode
這三個變量主要供函數內部使用。Lock用於設置鎖狀態,State用於設置JPEG狀態,而ErrorCode用於配置代碼錯誤。
- __IO uint32_t Context
JPEG上下文。
57.3.4 JPEG初始化流程總結
使用方法由HAL庫提供:
第1步:調用函數HAL_JPEG_Init進行初始化,但這個函數不需要初始化參數。
如果是JPEG編碼,可以通過函數HAL_JPEG_ConfigEncoding設置JPEG圖像的質量參數,質量越高,生成的JPEG文件越大、
第2步:調用編解碼函數
- 查詢式編解碼函數
HAL_JPEG_Encode
HAL_JPEG_Decode
- 中斷方式
HAL_JPEG_Encode_IT
HAL_JPEG_Decode_IT
- DMA方式
HAL_JPEG_Encode_DMA
HAL_JPEG_Decode_DMA
第4步:如果用戶之前的數據已經處理完畢,需要插入新數據,會調用函數HAL_JPEG_GetDataCallback
(1)如果新的數據已經準備好,需要調用函數HAL_JPEG_ConfigInputBuffer。如果新的數據沒有準備好,需要等待插入新數據時,可以調用函數HAL_JPEG_Pause(參數XferSelection被設置爲JPEG_PAUSE_RESUME_INPUT),待數據準備好後,可以調用HAL_JPEG_ConfigInputBuffer設置新的輸入緩衝和大小,然後調用函數HAL_JPEG_Resume恢復JPEG編解碼。
如果編解碼的數據已經處理完畢,可以調用函數HAL_JPEG_ConfigInputBuffer設置InDataLength參數爲0(此函數是在回調函數HAL_JPEG_GetDataCallback裏面被調用的)。
(2)函數HAL_JPEG_ConfigInputBuffer/HAL_JPEG_Pause/HAL_JPEG_Resume的工作機制允許應用程序以塊爲單位提供輸入數據。如果新的數據塊未準備好,可以調用函數HAL_JPEG_Pause暫停輸入,待數據準備好後,可以調用HAL_JPEG_ConfigInputBuffer設置新的輸入緩衝和大小,然後調用函數HAL_JPEG_Resume恢復JPEG編解碼。
(3)新的數據塊準備好後,可以在回調函數HAL_JPEG_GetDataCallback外面調用HAL_JPEG_ConfigInputBuffer 和 HAL_JPEG_Resume,但是爲了保持數據一致性問題,務必在回調函數HAL_JPEG_GetDataCallback裏面調用HAL_JPEG_Resume。
第5步:輸出緩衝區填充了給定大小的數據後,會調用回調函數HAL_JPEG_DataReadyCallback
(1)如果有數據空間存儲新數據塊,需要調用函數HAL_JPEG_ConfigOutputBuffer配置新存儲位置。如果沒有數據空間存儲新數據塊,需要等待有數據空間可用時,可以調用函數HAL_JPEG_Pause(參數XferSelection被設置爲JPEG_PAUSE_RESUME_INPUT),待有數據空間可用時,可以調用HAL_JPEG_ConfigOutputBuffe設置新的輸出緩衝,然後調用函數HAL_JPEG_Resume恢復JPEG編解碼。
(2)函數HAL_JPEG_ConfigOutputBuffe/HAL_JPEG_Pause/HAL_JPEG_Resume的工作機制允許應用程序以塊爲單位接收數據。當接收到數據塊時,應用程序可以暫停JPEG輸出來處理這些數據,比如解碼時YCbCr轉RGB或者編碼時數據存儲。
(3)新的數據空間準備好後,可以在回調函數HAL_JPEG_DataReadyCallback外面調用HAL_JPEG_ConfigOutputBuffer和 HAL_JPEG_Resume,但是爲了保持數據一致性問題,務必在回調函數HAL_JPEG_DataReadyCallback裏面調用HAL_JPEG_Resume。
第6步:其它相關函數
- JPEG解碼時,如果解碼成功,會調用回調函數HAL_JPEG_InfoReadyCallback。
- JPEG編碼操作結束後會調用回調函數HAL_JPEG_EncodeCpltCallback。
- JPEG解碼操作結束後,會調用回調函數HAL_JPEG_DecodeCpltCallback。
- 操作過程中出現錯誤,會調用回調函數HAL_JPEG_ErrorCallback,用戶可以調用函數HAL_JPEG_GetError獲取錯誤類型。
- HAL JPEG默認使用的是ISO/IEC 10918-1規格量化表,如果要修改,可以調用函數HAL_JPEG_SetUserQuantTables實現。
- 通過函數HAL_JPEG_GetState可以獲取JPEG狀態。
57.4 源文件stm32h7xx_hal_jpeg.c
這裏把我們把如下幾個常用到的函數做個說明:
- HAL_JPEG_Init
- HAL_JPEG_GetInfo
- HAL_JPEG_Decode_DMA
- HAL_JPEG_ConfigInputBuffer
- HAL_JPEG_ConfigOutputBuffer
57.4.1 函數HAL_JPEG_Init
函數原型:
HAL_StatusTypeDef HAL_JPEG_Init(JPEG_HandleTypeDef *hjpeg) { uint32_t acLum_huffmanTableAddr = (uint32_t)(&JPEG_ACLUM_HuffTable); uint32_t dcLum_huffmanTableAddr = (uint32_t)(&JPEG_DCLUM_HuffTable); uint32_t acChrom_huffmanTableAddr = (uint32_t)(&JPEG_ACCHROM_HuffTable); uint32_t dcChrom_huffmanTableAddr = (uint32_t)(&JPEG_DCCHROM_HuffTable); /* 檢測句柄是否有效 */ if(hjpeg == NULL) { return HAL_ERROR; } if(hjpeg->State == HAL_JPEG_STATE_RESET) { hjpeg->Lock = HAL_UNLOCKED; /* 初始化GPIO,NVIC等 */ HAL_JPEG_MspInit(hjpeg); } /* 設置JPEG狀態 */ hjpeg->State = HAL_JPEG_STATE_BUSY; /* 使能JPEG */ __HAL_JPEG_ENABLE(hjpeg); /* 關閉JPEG編解碼處理 */ hjpeg->Instance->CONFR0 &= ~JPEG_CONFR0_START; /* 關閉JPEG所有中斷 */ __HAL_JPEG_DISABLE_IT(hjpeg,JPEG_INTERRUPT_MASK); /* 清空輸入輸入FIFO緩衝 */ hjpeg->Instance->CR |= JPEG_CR_IFF; hjpeg->Instance->CR |= JPEG_CR_OFF; /* 清除所有標誌 */ __HAL_JPEG_CLEAR_FLAG(hjpeg,JPEG_FLAG_ALL); /* 初始化默認的量化表 */ hjpeg->QuantTable0 = (uint8_t *)((uint32_t)JPEG_LUM_QuantTable); hjpeg->QuantTable1 = (uint8_t *)((uint32_t)JPEG_CHROM_QuantTable); hjpeg->QuantTable2 = NULL; hjpeg->QuantTable3 = NULL; /* 初始化默認的霍夫曼表 */ if(JPEG_Set_HuffEnc_Mem(hjpeg, (JPEG_ACHuffTableTypeDef *)acLum_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcLum_huffmanTableAddr, (JPEG_ACHuffTableTypeDef *)acChrom_huffmanTableAddr, (JPEG_DCHuffTableTypeDef *)dcChrom_huffmanTableAddr) != HAL_OK) { hjpeg->ErrorCode = HAL_JPEG_ERROR_HUFF_TABLE; return HAL_ERROR; } /* 使能文件頭處理 */ hjpeg->Instance->CONFR1 |= JPEG_CONFR1_HDR; /* 復位JPEG輸入輸出計數 */ hjpeg->JpegInCount = 0; hjpeg->JpegOutCount = 0; /* 設置JPEG就緒 */ hjpeg->State = HAL_JPEG_STATE_READY; /* 設置無錯誤 Reset the JPEG ErrorCode */ hjpeg->ErrorCode = HAL_JPEG_ERROR_NONE; /* 清除上下文 */ hjpeg->Context = 0; /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數用於初始化JPEG。
函數參數:
- 第1個參數是JPEG_HandleTypeDef類型結構體指針變量,用於配置要初始化的參數,結構體變量成員的詳細介紹看本章3.3小節。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
注意事項:
- 函數HAL_JPEG_MspInit用於初始化JPEG的底層時鐘、NVIC等功能。需要用戶自己在此函數裏面實現具體的功能。由於這個函數是弱定義的,允許用戶在工程其它源文件裏面重新實現此函數。當然,不限制一定要在此函數裏面實現,也可以像早期的標準庫那樣,用戶自己初始化即可,更靈活些。
- 如果形參hjpeg的結構體成員State沒有做初始狀態,這個地方就是個坑。特別是用戶搞了一個局部變量JPEG_HandleTypeDef JpegHandle。
對於局部變量來說,這個參數就是一個隨機值,如果是全局變量還好,一般MDK和IAR都會將全部變量初始化爲0,而恰好這個 HAL_JPEG_STATE_RESET = 0x00U。
解決辦法有三
方法1:用戶自己初始JPEG底層。
方法2:定義JPEG_HandleTypeDef JpegHandle爲全局變量。
方法3:下面的方法
if(HAL_JPEG_DeInit(&JpegHandle) != HAL_OK) { Error_Handler(); } if(HAL_JPEG_Init(&Dma2dHandle) != HAL_OK) { Error_Handler(); }
使用舉例:
JPEG_HandleTypeDef JPEG_Handle; JPEG_Handle.Instance = JPEG; HAL_JPEG_Init(&JPEG_Handle);
57.4.2 函數HAL_JPEG_GetInfo
函數原型:
HAL_StatusTypeDef HAL_JPEG_GetInfo(JPEG_HandleTypeDef *hjpeg, JPEG_ConfTypeDef *pInfo) { uint32_t yblockNb, cBblockNb, cRblockNb; /* 檢測句柄是否有效 */ if((hjpeg == NULL) || (pInfo == NULL)) { return HAL_ERROR; } /* 讀取配置參數 */ if((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF_1) { pInfo->ColorSpace = JPEG_YCBCR_COLORSPACE; } else if((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == 0) { pInfo->ColorSpace = JPEG_GRAYSCALE_COLORSPACE; } else if((hjpeg->Instance->CONFR1 & JPEG_CONFR1_NF) == JPEG_CONFR1_NF) { pInfo->ColorSpace = JPEG_CMYK_COLORSPACE; } pInfo->ImageHeight = (hjpeg->Instance->CONFR1 & 0xFFFF0000U) >> 16; pInfo->ImageWidth = (hjpeg->Instance->CONFR3 & 0xFFFF0000U) >> 16; if((pInfo->ColorSpace == JPEG_YCBCR_COLORSPACE) || (pInfo->ColorSpace == JPEG_CMYK_COLORSPACE)) { yblockNb = (hjpeg->Instance->CONFR4 & JPEG_CONFR4_NB) >> 4; cBblockNb = (hjpeg->Instance->CONFR5 & JPEG_CONFR5_NB) >> 4; cRblockNb = (hjpeg->Instance->CONFR6 & JPEG_CONFR6_NB) >> 4; if((yblockNb == 1) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo->ChromaSubsampling = JPEG_422_SUBSAMPLING; /*16x8 block*/ } else if((yblockNb == 0) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; } else if((yblockNb == 3) && (cBblockNb == 0) && (cRblockNb == 0)) { pInfo->ChromaSubsampling = JPEG_420_SUBSAMPLING; } else /* 默認是 4:4:4*/ { pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; } } else { pInfo->ChromaSubsampling = JPEG_444_SUBSAMPLING; } pInfo->ImageQuality = JPEG_GetQuality(hjpeg); /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數主要用於解碼JPEG時獲取相關圖像信息,比如圖像質量,圖像長寬等。
函數參數:
- 第1個參數是JPEG_HandleTypeDef類型結構體指針變量,用於配置要初始化的參數,結構體變量成員的詳細介紹看本章3.3小節。
- 第2個參數是JPEG_ConfTypeDef類型結構體指針變量,用於獲取JPEG的配置信息,結構體變量成員的詳細介紹看本章3.2小
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
JPEG_HandleTypeDef JPEG_Handle; JPEG_ConfTypeDef JPEG_Info; HAL_JPEG_GetInfo(&JPEG_Handle, &JPEG_Info);
57.4.3 函數HAL_JPEG_Decode_DMA
函數原型:
HAL_StatusTypeDef HAL_JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg ,uint8_t *pDataIn ,uint32_t InDataLength ,uint8_t *pDataOutMCU ,uint32_t OutDataLength) { /* 檢測參數 */ assert_param((InDataLength >= 4)); assert_param((OutDataLength >= 4)); /* 檢測參數 */ if((hjpeg == NULL) || (pDataIn == NULL) || (pDataOutMCU == NULL)) { return HAL_ERROR; } /* 上鎖 */ __HAL_LOCK(hjpeg); if(hjpeg->State == HAL_JPEG_STATE_READY) { /* 設置JPEG忙 */ hjpeg->State = HAL_JPEG_STATE_BUSY_DECODING; /* 設置JPEG上下文,工作在DMA界面狀態 */ hjpeg->Context &= ~(JPEG_CONTEXT_OPERATION_MASK | JPEG_CONTEXT_METHOD_MASK); hjpeg->Context |= (JPEG_CONTEXT_DECODE | JPEG_CONTEXT_DMA); /* 設置輸入輸出緩衝地址和大小 */ hjpeg->pJpegInBuffPtr = pDataIn; hjpeg->pJpegOutBuffPtr = pDataOutMCU; hjpeg->InDataLength = InDataLength; hjpeg->OutDataLength = OutDataLength; /* 復位輸入輸出緩衝計數 */ hjpeg->JpegInCount = 0; hjpeg->JpegOutCount = 0; /* 初始化解碼處理 */ JPEG_Init_Process(hjpeg); /* 啓動JPEG解碼處理,使用DMA方式 */ JPEG_DMA_StartProcess(hjpeg); } else { /* 解鎖 */ __HAL_UNLOCK(hjpeg); return HAL_BUSY; } /* 返回HAL_OK */ return HAL_OK; }
函數描述:
此函數用於啓動JPEG的DMA方式解碼。
函數參數:
- 第1個參數是JPEG_HandleTypeDef類型結構體指針變量,用於配置要初始化的參數,結構體變量成員的詳細介紹看本章3.3小節。
- 第2個參數是輸入數據緩衝地址。
- 第3個參數輸入數據大小,單位字節。
- 第4個參數是輸出緩衝地址。
- 第5個參數是輸出緩衝大小,單位字節。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
/* ********************************************************************************************************* * 函 數 名: JPEG_Decode_DMA * 功能說明: JPEG解碼 * 形 參: hjpeg JPEG_HandleTypeDef句柄指針 * FrameSourceAddress 數據地址 * FrameSize 數據大小 * DestAddress 目的數據地址 * 返 回 值: HAL_ERROR表示配置失敗,HAL_OK表示配置成功 * HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出 ********************************************************************************************************* */ uint32_t JPEG_Decode_DMA(JPEG_HandleTypeDef *hjpeg, uint32_t FrameSourceAddress ,uint32_t FrameSize, uint32_t DestAddress) { JPEGSourceAddress = FrameSourceAddress ; FrameBufferAddress = DestAddress; Input_frameIndex = 0; Input_frameSize = FrameSize; /* 設置標誌,0表示開始解碼,1表示解碼完成 */ Jpeg_HWDecodingEnd = 0; /* 啓動JPEG解碼 */ HAL_JPEG_Decode_DMA(hjpeg ,(uint8_t *)JPEGSourceAddress ,CHUNK_SIZE_IN , (uint8_t *)FrameBufferAddress ,CHUNK_SIZE_OUT); return HAL_OK; }
57.4.4 函數HAL_JPEG_ConfigInputBuffer
函數原型:
void HAL_JPEG_ConfigInputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewInputBuffer, uint32_t InDataLength) { hjpeg->pJpegInBuffPtr = pNewInputBuffer; hjpeg->InDataLength = InDataLength; }
函數描述:
此函數用於配置編解碼輸入緩衝地址和數據大小。
函數參數:
- 第1個參數是JPEG_HandleTypeDef類型結構體指針變量,用於配置要初始化的參數,結構體變量成員的詳細介紹看本章3.3小節。
- 第2個參數是輸入緩衝地址。
- 第3個參數是輸入緩衝大小,單位字節。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
/* ********************************************************************************************************* * 函 數 名: HAL_JPEG_GetDataCallback * 功能說明: JPEG回調函數,用於從輸入地址獲取新數據繼續解碼 * 形 參: hjpeg JPEG_HandleTypeDef 句柄指針 * NbDecodedData 上一輪已經解碼的數據大小,單位字節 * 返 回 值: 無 ********************************************************************************************************* */ void HAL_JPEG_GetDataCallback(JPEG_HandleTypeDef *hjpeg, uint32_t NbDecodedData) { uint32_t inDataLength; /* 更新已經解碼的數據大小 */ Input_frameIndex += NbDecodedData; /* 如果當前已經解碼的數據小於總文件大小,繼續解碼 */ if( Input_frameIndex < Input_frameSize) { /* 更新解碼數據位置 */ JPEGSourceAddress = JPEGSourceAddress + NbDecodedData; /* 更新下一輪要解碼的數據大小 */ if((Input_frameSize - Input_frameIndex) >= CHUNK_SIZE_IN) { inDataLength = CHUNK_SIZE_IN; } else { inDataLength = Input_frameSize - Input_frameIndex; } } else { inDataLength = 0; } /* 更新輸入緩衝 */ HAL_JPEG_ConfigInputBuffer(hjpeg,(uint8_t *)JPEGSourceAddress, inDataLength); }
57.4.5 函數HAL_JPEG_ConfigOutputBuffer
函數原型:
void HAL_JPEG_ConfigOutputBuffer(JPEG_HandleTypeDef *hjpeg, uint8_t *pNewOutputBuffer, uint32_t OutDataLength) { hjpeg->pJpegOutBuffPtr = pNewOutputBuffer; hjpeg->OutDataLength = OutDataLength; }
函數描述:
此函數用於配置編解碼輸出緩衝地址和數據大小。
函數參數:
- 第1個參數是JPEG_HandleTypeDef類型結構體指針變量,用於配置要初始化的參數,結構體變量成員的詳細介紹看本章3.3小節。
- 第2個參數是輸出緩衝地址。
- 第3個參數是輸出緩衝大小,單位字節。
- 返回值,返回HAL_ERROR表示配置失敗,HAL_OK表示配置成功,HAL_BUSY表示忙(操作中),HAL_TIMEOUT表示時間溢出。
使用舉例:
/* ********************************************************************************************************* * 函 數 名: HAL_JPEG_DataReadyCallback * 功能說明: JPEG回調函數,用於輸出緩衝地址更新 * 形 參: hjpeg JPEG_HandleTypeDef 句柄指針 * pDataOut 輸出數據緩衝 * OutDataLength 輸出數據大小,單位字節 * 返 回 值: 無 ********************************************************************************************************* */ void HAL_JPEG_DataReadyCallback (JPEG_HandleTypeDef *hjpeg, uint8_t *pDataOut, uint32_t OutDataLength) { /* 更新JPEG輸出地址 */ FrameBufferAddress += OutDataLength; HAL_JPEG_ConfigOutputBuffer(hjpeg, (uint8_t *)FrameBufferAddress, CHUNK_SIZE_OUT); }
57.5 總結
本章節就爲大家講解這麼多,JPEG功能用到的地方還是比較多的,建議熟練使用。