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: GC320 compositing issue

Part Number: AM5728

Tool/software: Linux

I am successfully using the GC320 in the AM5728 to composite ( "multiblit" ) 2 images, but I cannot seem to set the destination rectangle ( for placement in the destination surface ) for either input image. When I set the target rectangle, I immediately get the error: gcvSTATUS_NOT_SUPPORTED.

Currently, I blit the source image ( 640x480) of the first index into the target surface with the same dimensions as the target surface ( 640x480 ). I then change the rectangle for a different source image ( 640x480 ) of the second index with the API call "gco2D_SetSource(m_Engine2d, &sourceIRRect)".

The rectangle is defined as follows:

    // Source Rectangle
    uint modifierSrcIR = 100;
    sourceIRRect.left = modifierSrcIR;
    sourceIRRect.top = modifierSrcIR;
    sourceIRRect.right = sourceIRRect.left + modifierSrcIR*3; 
    sourceIRRect.bottom = sourceIRRect.top + modifierSrcIR*3; 

This results in an image as shown below. The second image is "cropped" with the rectangle define above and placed in the destination image at the location of this same rectangle.

I've studied the examples in the ti-gc320-test repository for the MultiBlit functionality, and they call "gco2D_SetTargetRect" and "gco2D_SetClipping". When I call "gco2D_SetTargetRect", I get the error: gcvSTATUS_NOT_SUPPORTED.

http://git.ti.com/graphics/ti-gc320-test/blobs/ti-5.0.11.p7/tests/src/test/hal/common/UnitTest/units/gal2D/blit/MultiSourceBlit/014/014.c

How can I set the target rectangle for one of the multiblit input frames? Thanks.

My code that fails:

/**
 * gc320 renderCompositedFrames()
 * Purpose: Perform a render cycle for compositing 2 input rames together
 *
 * @param inputBuffer1 - DMABUF type input buffer
 * @param inputBuffer2 - DMABUF type input buffer
 *
 * @return Return bool success or failure
 */
gctBOOL Gc320::renderCompositedFrames(dmabuf_buffer *inputBuffer1, dmabuf_buffer *inputBuffer2) {

    // Track Status
    gceSTATUS status;

    // Destination Rectangle
    gcsRECT targetRect;
    gcsRECT sourceVLRect;
    gcsRECT sourceIRRect;
    gcsRECT destinationVLRect;
    gcsRECT destinationIRRect;

    // Set the destination size / stride - NOTE: Height here because we are rotating
    quint32 hijackedDestinationStride = inputBuffer1->width * 4; // RGBA

    // This modifier moves the rectangle of the final image from the Temp Destination image
    uint modifierTargetRect = 0;
    targetRect.left = 0 + modifierTargetRect;
    targetRect.top = 0 + modifierTargetRect;
    targetRect.right = FRAME_WIDTH;// - modifierTargetRect; // These affect the output image ( destination rect )
    targetRect.bottom = FRAME_HEIGHT;// - modifierTargetRect; // These affect the output image ( destination rect )

    // VL Source Rectangle
    uint modifierSrcVL = 0;
    sourceVLRect.left = 0 + modifierSrcVL;
    sourceVLRect.top = 0 + modifierSrcVL;
    sourceVLRect.right = sourceVLRect.left + FRAME_WIDTH; // These affect the input image ( source rect )
    sourceVLRect.bottom = sourceVLRect.top + FRAME_HEIGHT; // These affect the input image ( source rect )

    // IR Source Rectangle
    uint modifierSrcIR = 100;
    sourceIRRect.left = 0 + modifierSrcIR;
    sourceIRRect.top = 0 + modifierSrcIR;
    sourceIRRect.right = sourceIRRect.left + modifierSrcIR*3; // These affect the input image ( source rect )
    sourceIRRect.bottom = sourceIRRect.top + modifierSrcIR*3; // These affect the input image ( source rect )

    // VL Destination Rectangle
    uint modifierDstVL = 0;
    destinationVLRect.left = 0 + modifierDstVL;
    destinationVLRect.top = 0 + modifierDstVL;
    destinationVLRect.right = destinationVLRect.left + FRAME_WIDTH; // These affect the input image ( source rect )
    destinationVLRect.bottom = destinationVLRect.top + FRAME_HEIGHT; // These affect the input image ( source rect )

    // IR Destination Rectangle
    uint modifierDstIR = 100;
    destinationIRRect.left = 0 + modifierDstIR;
    destinationIRRect.top = 0 + modifierDstIR;
    destinationIRRect.right = destinationIRRect.left + modifierDstIR; // These affect the input image ( source rect )
    destinationIRRect.bottom = destinationIRRect.top + modifierDstIR; // These affect the input image ( source rect )

    // Set the underlying buffer for VL
    void *VLDataPtr = omap_bo_map(inputBuffer1->bo[0]); // mmap the DMABUF
    qDebug() << VLDataPtr;
    configureYuYvSourceSurfaceForVL(VLDataPtr);

    // Set the underlying buffer for IR
    void *IRDataPtr = omap_bo_map(inputBuffer2->bo[0]); // mmap the DMABUF
    qDebug() << IRDataPtr;
    configureYuYvSourceSurfaceForIR(IRDataPtr);

//#ifdef DEBUG_GC320
#if 0

        {
            // display -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace YCbCr inputVL.yuv
            QString filename = QString("/home/root/inputVL.yuv");
            QFile d(filename);d.open(QFile::WriteOnly);QDataStream ds(&d);
            ds.writeRawData((const char*)VLDataPtr,inputBuffer1->width*inputBuffer1->height*2);
            d.flush();d.close();sync();
        }

        {
            // display -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace YCbCr inputIR.yuv
            QString filename = QString("/home/root/inputIR.yuv");
            QFile d(filename);d.open(QFile::WriteOnly);QDataStream ds(&d);
            ds.writeRawData((const char*)IRDataPtr,inputBuffer2->width*inputBuffer2->height*2);
            d.flush();d.close();sync();
            qDebug() << "sudo cp ~/am57xx/build/exported-nfs/home/root/inputVL.yuv . ; display -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace YCbCr inputVL.yuv &";
            qDebug() << "sudo cp ~/am57xx/build/exported-nfs/home/root/inputIR.yuv . ; display -size 640x480 -depth 8 -sampling-factor 4:2:2 -colorspace YCbCr inputIR.yuv";
        }

        sleep(86400);

    }

#endif

    // clear dest temp with color
    gcmONERROR(Gal2DCleanSurface(m_Hal, m_TempDstSurf, COLOR_ARGB8(0xFF, 0x00, 0xFF, 0x00)));
    gcmONERROR(Gal2DCleanSurface(m_Hal, m_DstSurf, COLOR_ARGB8(0xFF, 0x00, 0x00, 0xFF)));

    // Index 1 for VL and index 2 for IR

    ////////////////////// VL //////////////////////////////////////////

    gcmONERROR(gco2D_SetCurrentSourceIndex(m_Engine2d, 0));

    gcmONERROR(gco2D_SetGdiStretchMode(m_Engine2d, gcvTRUE));

    // TODO: Fix this
    m_VLSrcStride = 1280;

    gcmONERROR(gco2D_SetGenericSource(
                   m_Engine2d,
                   (gctUINT32_PTR)&m_VLSrcPhysAddr, 1,
                   (gctUINT32_PTR)&m_VLSrcStride, 1,
                   gcvLINEAR,
                   m_VLSrcFormat,
                   gcvSURF_0_DEGREE,
                   (gctUINT32)inputBuffer1->width,
                   (gctUINT32)inputBuffer1->height));

    gcmONERROR(gco2D_SetSource(m_Engine2d, &sourceVLRect));

    // These lines fail and cause "renderCompositedFrames(1670) failed:gcvSTATUS_NOT_SUPPORTED"
    gcmONERROR(gco2D_SetTargetRect(m_Engine2d, &destinationVLRect));

    gcmONERROR(gco2D_SetClipping(m_Engine2d, &destinationVLRect));

    gcmONERROR(gco2D_SetROP(m_Engine2d, 0xCC, 0xCC));

    ////////////////////// IR //////////////////////////////////////////

    gcmONERROR(gco2D_SetCurrentSourceIndex(m_Engine2d, 1));

    gcmONERROR(gco2D_SetGdiStretchMode(m_Engine2d, gcvTRUE));

    // TODO: Fix this
    m_IRSrcStride = 1280;

    gcmONERROR(gco2D_SetGenericSource(
                   m_Engine2d,
                   (gctUINT32_PTR)&m_IRSrcPhysAddr, 1,
                   (gctUINT32_PTR)&m_IRSrcStride, 1,
                   gcvLINEAR,
                   m_IRSrcFormat,
                   gcvSURF_0_DEGREE,
                   (gctUINT32)inputBuffer2->width,
                   (gctUINT32)inputBuffer2->height));

    gcmONERROR(gco2D_SetSource(m_Engine2d, &sourceIRRect));

    // These lines fail and cause "renderCompositedFrames(1670) failed:gcvSTATUS_NOT_SUPPORTED"
    gcmONERROR(gco2D_SetTargetRect(m_Engine2d, &destinationIRRect));

    gcmONERROR(gco2D_SetClipping(m_Engine2d, &destinationIRRect));

    gcmONERROR(gco2D_SetROP(m_Engine2d, 0xCC, 0xCC));

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

    gcmONERROR(gco2D_SetGenericTarget(
                   m_Engine2d,
                   (gctUINT32_PTR)&m_DstPhysAddr, 1,
                   (gctUINT32_PTR)&hijackedDestinationStride, 1,
                   gcvLINEAR,
                   m_DstFormat,
                   gcvSURF_0_DEGREE,
                   (gctUINT32)inputBuffer2->width,
                   (gctUINT32)inputBuffer2->height));

    gcmONERROR(gco2D_MultiSourceBlit(m_Engine2d, 0x3, &targetRect, 1));

    gcmONERROR(gco2D_Flush(m_Engine2d));

    gcmONERROR(gcoHAL_Commit(m_Hal, gcvTRUE));

#ifdef DEBUG_GC320

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

    // Save RGB24
    {

        // sudo cp ~/am57xx/build/exported-nfs/home/root/gc320-yuv-to-rgb-MULTIBLIT.rgb . ; sudo convert -depth 8 -size 612x432+0 RGBA:gc320-yuv-to-rgb-MULTIBLIT.rgb gc320-yuv-to-rgb-MULTIBLIT.png ; eog gc320-yuv-to-rgb-MULTIBLIT.png
        qDebug() << QString("Writing the frame out to /home/root/gc320-yuv-to-rgb-MULTIBLIT");
        QString filename = QString("/home/root/gc320-yuv-to-rgb-MULTIBLIT.rgb");
        QFile d(filename);
        d.open(QFile::WriteOnly);
        QDataStream ds(&d);
        ds.writeRawData((const char*)m_DstVirtAddr,inputBuffer2->width*inputBuffer2->height*4);
        d.flush();
        d.close();
        sync();
        QString cmd = QString("sudo cp ~/am57xx/build/exported-nfs/home/root/gc320-yuv-to-rgb-MULTIBLIT.rgb . ; sudo convert -depth 8 -size %1x%2+0 RGBA:gc320-yuv-to-rgb-MULTIBLIT.rgb gc320-yuv-to-rgb-MULTIBLIT.png ; eog gc320-yuv-to-rgb-MULTIBLIT.png &").arg(inputBuffer2->width).arg(inputBuffer2->height);
        qDebug() << cmd;

        QTextStream stream( &m_DebugScript );
        stream << cmd << endl;

    }

#endif

    return gcvTRUE;

OnError:
    fprintf(stderr,"%s(%d) failed:%s\n",__FUNCTION__, __LINE__, gcoOS_DebugStatus2Name(status));
    return gcvFALSE;

}