This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/AM5728:使用基于 dmabuf 的应用程序将 GC320 YUV 转换为 RGBA

Guru**** 2609945 points
Other Parts Discussed in Thread: AM5728

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/654666/linux-am5728-gc320-yuyv-to-rgba-conversion-using-dmabuf-based-app

器件型号:AM5728

工具/软件:Linux

您好!

我为我们的一位客户发布此帖子。

"

我正在从 AM5728的 VIP 端口捕获 YUYV 格式摄像机帧。 我将这些帧提交给 GC320、目的是将它们的格式转换为 RGBA 帧。 Galcore 驱动程序版本为5.0.11.33433。 我将 V4L2 DMABUF 直接传递到 GC320、为了进行调试、我将在 GC320呈现前后保存原始 YUV 文件。 输入帧为640x480 YUV、输出为640x480 RGBA。 我已附加以下图片。 左侧的图像是来自相机的 YUYV (由于 Ubuntu 的图像查看器而被编辑),右侧的图像是由 GC320转换的 RGBA 帧。 很明显、GC320的"种类"转换图像-上半部分看起来不错。 但是、图像的下半部分是某种伪影。 这让我相信我使用 GC320 API 进行转换的配置是错误的。 我在 Arago/Yocto ti-gc320-test 样片中研究了 GC320示例、并将我的 GC320转换代码放在下面-如果能帮助理解它的错误、我将不胜感激。  

"

(将在单独的帖子中发送附件)

GC320格式函数:

/**

* gc320渲染格式转换 YUVtoRGBA()

*用途:执行渲染周期以将帧从 YUYV 转换为 RGBA

*

*@返回 bool 成功或失败

*

gctBOOL Gc320::渲染格式转换 YUVtoRGBA(){

 

   gceSTATUS 状态;

 

   //目标矩形

   gcsRECT targetRect;

   gcsRECT sourceRect;

 

   //目标矩形

   targetRect.Left = 0;

   targetRect.top = 0;

   targetRect.right = frame_width;//这些会影响输出图像(目标矩形)

   targetRect.bottom = frame_height;//这些会影响输出图像(目标矩形)

 

   //源矩形

   sourceRect.left = 0;

   sourceRect.top = 0;

   sourceRect.right = frame_width;//这些会影响输入图像(源矩形)

   sourceRect.bottom = frame_height;//这些会影响输入图像(源矩形)

 

   QElapsedTimer 计时器;

   timer.restart();

 

   //为目标矩形设置剪切矩形

   gcmONERROR (gco2D_SetClipping (m_Engine2d、&targetRect));

 

   //设置内核大小

   gcmONERROR (gco2D_SetKernelSize (m_Engine2d、1、1));

 

   gcmONERROR (gco2D_FilterBlitEx2 (m_Engine2d、

               (gctuint32_ptr)&m_SrcPhysAddr、1、

               (gctuint32_ptr)&m_SrcStride、1、

               gcvLINEAR、m_SrcFormat、gcvSURF_0_degree、

               m_SrcWidth、m_SrcHeight、(gcsRECT_PTR)&sourceRect、

               (gctuint32_ptr)&m_DstPhysAddr、1、(gctuint32_ptr)&m_DstStride、1、

               gcvLINEAR、m_DstFormat、gcvSURF_0_degree、

               m_DstWidth、m_DstHeight、(gcsRECT_PTR)&targetRect、

               gcvNULL));

 

   gcmONERROR (gcode_Flush (m_Engine2d));

 

   //将当前命令缓冲区提交到硬件,并等待硬件完成

   gcmONERROR (gcHAL_commit (m_hal、gcvTRUE));

 

   qDebug()<<"Rendered:"<< timer.Elapsed();

 

#if 1.

 

   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

   //保存 RGB24

   {

       //转换-depth 8 -size 640x480+0 RGBA:gc320.RGB gc320.png;eog gc320.png

       qDebug()<< QString ("将帧写入到/home/root/gc320.rgb);

       QString fileName = QString ("/home/root/gc320.rgb);

       QFile d (filename);

       d. open (QFile::WriteOnly);

       QDataStream DS (&d);

       qDebug()<<"正在写入数据...";

       ds.writeRawData (((const char*) m_DstVirtAddr、frame_width*frame_height*4);

       D.flush();

       D.Close();

       SYNC();

       qDebug()<<"Done writing";

   }

 

   睡眠(100);

 

#endif

 

   返回 gcvTRUE;

 

onerror:

   fprintf (stderr、"%s"(%d)失败:%s\n"、__function__、__line__、gcos_DebugStatus2Name (status);

   返回 gcvFALSE;

 

Linux 内核版本:

uname -r

4.4.41.

GC320 Galcore 驱动程序版本:

CD /lib/modules/4.4.41/extra;insmod galcore.ko baseAddress=0x80000

000 physSize=0x80000000

[8014.626644] GC320 IRQ:304

[8014.629403] Galcore 版本5.0.11.33433

此致、

-Gunter

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是 GC320输入和输出端图像的附件。

    e2e.ti.com/.../GC320-YUYV-to-RGBA.zip

    此致、

    -Gunter

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    请查看此链接:
    git.ti.com/.../YUV

    BR
    玛格丽塔
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Margarita、

    我是原始问题的客户。

    我最终确定了这一点、但我认为 gc320 libs 可能存在问题。 它呈现为帧的一半的原因是 gcoSURF_QueryFormat 返回的源跨度不正确。

    我使用以下代码设置源曲面:

    /*创建包装程序 gcoSURF 表面对象,因为我们要映射用户
    *分配的缓冲池应为 gcvPOOL_user */
    status = gcoSURF_construct(
    gcvNULL、
    M_SrcWidth、
    M_SrcHeight、
    1、
    gcvSURF_bitmap、
    GcvSURF_UYVY、
    gcvPOOL_user、
    &m_SrcSurf);
    如果(状态< 0){
    fprintf (stderr、"*error*无法创建 gcoSURF 对象\n");
    返回 gcvFALSE;
    } 

    然后我立即调用 QueryFormat:

    /*计算所需缓冲区的大小。 将 gcoSURF_QueryFormat API 用于
    *格式参数描述符-包含有关格式 AS 的信息
    * Vivante 驱动程序所需的
    *
    STATUS = gcoSURF_QueryFormat (m_Format、INFO);
    如果(状态< 0){
    fprintf (stderr、"*error*无法创建查询格式信息\n");
    返回 gcvFALSE;
    } 

    然后、我立即打印每像素的位数、如下所示:

    qDebug()<< info[0]-> bitsPerPixel; 

    并打印2560 (640 * 4)。  

    这是错误的、因为我指定了 gcvSURF_UYVU 的像素格式... 应为16位。  

    当我稍后使用代码转换格式时-我必须强制源代码跨度为1280。 之后、帧将完全呈现正常:

    //对于 YUYV,GC320 Lib 的像素跨度可能有问题,其中它说它是32位
    的标准32位的字形 Striding = 1280;
    
    ...
    
    gcmONERROR (gco2D_FilterBlitEx2 (m_Engine2d、
    (gctuint32_ptr)&m_SrcPhysAddr、1、
    (gctuint32_ptr) hijkedStride、1、
    gcvLINEAR、m_SrcFormat、gcvSURF_0_degree、
    m_SrcWidth、m_SrcHeight、(gcsRECT_PTR)&sourceRect、
    (gctuint32_ptr)&m_DstPhysAddr、1、(gctuint32_ptr)&m_DstStride、1、
    gcvLINEAR、m_DstFormat、gcvSURF_0_degree、
    m_DstWidth、m_DstHeight、(gcsRECT_PTR)&targetRect、
    gcvNULL)); 

    这是一个错误还是我误解了什么? 谢谢。