Displaying YCbCr data and RGB data together using a hardware accelerator

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Displaying YCbCr data and RGB data together using a hardware accelerator

      Hello,

      I'm using a custom board with a STM32H745 MCU (STemWin v5.44). The color conversion routine is GUICC_M565.

      I need to display some JPEG data among other things.
      For converting JPEG data to RGB data I applied hardware JPEG decoder that converts JPEG data to YCbCr data and then I converted YCbCr data to RGB data by software.
      For displaying RGB data I applied DMA2D. I call _DrawBitmap() -> it calls LCD_DrawBitmap() -> it calls LCD_LL_DrawBitmap16bpp() in LCDConf.c.

      Here is a screen from the board displaying a JPEG data and some non-JPEG data (just a white text on a red background) above the JPEG picture. Works fine.


      The next I tried to do is to use DMA2D not only for displaying RGB data but for displaying YCbCr data without wasting time for convertion YCbCr to RGB.
      I modified some functions and now I've got the screen:


      RGB data is shown incorrect. I think there is some mess in data types when calling LCD_LL_DrawBitmap16bpp().

      So is it possible to display both data types (YCbCr and RGB) at the same time using DMA2D?

      Here's a part of the code:

      C Source Code

      1. /*** displaying some image and text from main.c ***/
      2. ...
      3. GUI_JPEG_SetpfDrawEx(JPEG_X_Draw);
      4. GUI_JPEG_Draw(_acpic, sizeof(_acpic), 0, 0);
      5. GUI_SetFont(GUI_FONT_20_ASCII);
      6. GUI_SetBkColor(GUI_RED);
      7. GUI_SetColor(GUI_WHITE);
      8. GUI_DispStringAt("A non-JPEG data", 100, 10);
      9. ...
      10. /*** _DrawBitmap() from main.c ***/
      11. void _DrawBitmap(int x, int y, void const * p, int xSize, int ySize, int BytesPerLine, int BitsPerPixel) {
      12. #if (GUI_WINSUPPORT)
      13. GUI_RECT r;
      14. #endif
      15. #if (GUI_WINSUPPORT)
      16. WM_ADDORG(x,y);
      17. r.x1 = (r.x0 = x) + xSize-1;
      18. r.y1 = (r.y0 = y) + ySize-1;
      19. WM_ITERATE_START(&r) {
      20. #endif
      21. LCD_DrawBitmap(x, y, xSize, ySize, 1, 1, BitsPerPixel, BytesPerLine, p, NULL);
      22. #if (GUI_WINSUPPORT)
      23. } WM_ITERATE_END();
      24. #endif
      25. }
      26. /*** JPEG_X_Draw() from main.c ***/
      27. int JPEG_X_Draw(GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0) {
      28. void * pData;
      29. uint32_t Size;
      30. JPEG_ConfTypeDef JPEG_Info;
      31. pData = *(void **)p;
      32. Size = *(uint32_t *)(p + 4);
      33. JPEG_Decode(&hjpeg, (uint32_t)pData, Size, (uint32_t)outBuf);
      34. while (Jpeg_HWDecodingEnd == 0);
      35. HAL_JPEG_GetInfo(&hjpeg, &JPEG_Info);
      36. chroma_sub_sampling = JPEG_Info.ChromaSubsampling;
      37. jpeg_draw = 1;
      38. _DrawBitmap(x0, y0, outBuf, Custom_JPEG_Info.JPEG_Info.ImageWidth, Custom_JPEG_Info.JPEG_Info.ImageHeight, Custom_JPEG_Info.BytesPerLine, Custom_JPEG_Info.BitsPerPixel);
      39. jpeg_draw = 0;
      40. return 0;
      41. }
      42. /*** LCD_LL_DrawBitmap16bpp() from LCDConf.c ***/
      43. ...
      44. extern uint8_t jpeg_draw;
      45. extern uint32_t chroma_sub_sampling;
      46. extern void DMA2D_CopyBufferJPEG(uint32_t *pSrc, uint32_t *pDst, uint16_t xsize, uint16_t ysize, uint32_t ChromaSampling, uint32_t OffLineSrc, uint32_t OffLineDst);
      47. ...
      48. void LCD_LL_DrawBitmap16bpp(int LayerIndex, int x, int y, U16 const * p, int xSize, int ySize, int BytesPerLine)
      49. {
      50. U32 BufferSize, AddrDst;
      51. int OffLineSrc, OffLineDst;
      52. switch (jpeg_draw) {
      53. case 0:
      54. BufferSize = GetBufferSize(LayerIndex);
      55. AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
      56. OffLineSrc = (BytesPerLine / 2) - xSize;
      57. OffLineDst = layer_prop[LayerIndex].xSize - xSize;
      58. DMA2D_CopyBuffer(LayerIndex, (void *)p, (void *)AddrDst, xSize, ySize, OffLineSrc, OffLineDst);
      59. break;
      60. case 1:
      61. BufferSize = GetBufferSize(LayerIndex);
      62. AddrDst = layer_prop[LayerIndex].address + BufferSize * layer_prop[LayerIndex].buffer_index + (y * layer_prop[LayerIndex].xSize + x) * layer_prop[LayerIndex].BytesPerPixel;
      63. OffLineSrc = (BytesPerLine / 2) - xSize;
      64. OffLineDst = layer_prop[LayerIndex].xSize - xSize;
      65. DMA2D_CopyBufferJPEG((void *)p, (void *)AddrDst, xSize, ySize, chroma_sub_sampling, OffLineSrc, OffLineDst);
      66. break;
      67. }
      68. }
      69. /*** DMA2D_CopyBufferJPEG() from main.c***/
      70. void DMA2D_CopyBufferJPEG(uint32_t *pSrc, uint32_t *pDst, uint16_t xsize, uint16_t ysize, uint32_t ChromaSampling, uint32_t OffLineSrc, uint32_t OffLineDst)
      71. {
      72. uint32_t cssMode = LL_DMA2D_CSS_420, inputLineOffset = 0;
      73. LL_DMA2D_IsTransferOngoing(DMA2D);
      74. if(ChromaSampling == JPEG_420_SUBSAMPLING)
      75. {
      76. cssMode = LL_DMA2D_CSS_420;
      77. inputLineOffset = xsize % 16;
      78. if(inputLineOffset != 0)
      79. {
      80. inputLineOffset = 16 - inputLineOffset;
      81. }
      82. }
      83. else if(ChromaSampling == JPEG_444_SUBSAMPLING)
      84. {
      85. cssMode = LL_DMA2D_CSS_444;
      86. inputLineOffset = xsize % 8;
      87. if(inputLineOffset != 0)
      88. {
      89. inputLineOffset = 8 - inputLineOffset;
      90. }
      91. }
      92. else if(ChromaSampling == JPEG_422_SUBSAMPLING)
      93. {
      94. cssMode = LL_DMA2D_CSS_422;
      95. inputLineOffset = xsize % 16;
      96. if(inputLineOffset != 0)
      97. {
      98. inputLineOffset = 16 - inputLineOffset;
      99. }
      100. }
      101. /*##-1- Configure the DMA2D Mode, Color Mode and output offset #############*/
      102. LL_DMA2D_SetMode(DMA2D, LL_DMA2D_MODE_M2M_PFC);
      103. LL_DMA2D_SetOutputColorMode(DMA2D, LL_DMA2D_OUTPUT_MODE_RGB565);
      104. LL_DMA2D_SetLineOffset(DMA2D, OffLineDst);
      105. LL_DMA2D_FGND_SetColorMode(DMA2D, LL_DMA2D_INPUT_MODE_YCBCR);
      106. LL_DMA2D_FGND_SetAlphaMode(DMA2D, LL_DMA2D_ALPHA_MODE_REPLACE);
      107. LL_DMA2D_FGND_SetAlpha(DMA2D, 0xFF);
      108. LL_DMA2D_FGND_SetLineOffset(DMA2D, inputLineOffset);
      109. LL_DMA2D_FGND_SetRBSwapMode(DMA2D, LL_DMA2D_RB_MODE_REGULAR);
      110. LL_DMA2D_FGND_SetAlphaInvMode(DMA2D, LL_DMA2D_ALPHA_REGULAR);
      111. LL_DMA2D_FGND_SetChrSubSampling(DMA2D, cssMode);
      112. LL_DMA2D_FGND_SetMemAddr(DMA2D, (uint32_t)pSrc);
      113. LL_DMA2D_SetOutputMemAddr(DMA2D, (uint32_t)pDst);
      114. LL_DMA2D_SetNbrOfPixelsPerLines(DMA2D, xsize);
      115. LL_DMA2D_SetNbrOfLines(DMA2D, ysize);
      116. LL_DMA2D_Start(DMA2D);
      117. LL_DMA2D_IsTransferOngoing(DMA2D);
      118. }
      Display All

      Also LCDConf files in attach.

      Thank you.
      Files
      • LCDConf.zip

        (7.53 kB, downloaded 414 times, last: )
      Regards,

      Anthony