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.
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.
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; }
It looks as though the feature is not available in TiSDK.
Page 53 of the Vivate_2D_API shows that gco2d_SetTargetRect requires the Multi-Source EX2 Feature of the API.
I've checked for gco2D_SetTargetRect with the following code:
if(gcoHAL_IsFeatureAvailable(m_Hal, gcvFEATURE_2D_MULTI_SOURCE_BLT_EX2) == gcvTRUE){ qDebug() << "Set Target Rect is Available"; }
The feature is not available based on that check.
Is this true? We cannot set the target rect in a multisource blit?
Thanks
Phil,
The last scenario in your diagram can be supported through GC320 as well however not through the Multi-source EX2 feature as you have noted. The EX2 feature enables multi-source blits with scaling/rotation. If you want to do scaling/rotation along with multisource blits on AM5x you would need to serialize the operations. Take a look at the StretchBlit006 unit-test, which performs alpha blending of two sources with scaling on one.
Thanks,
Gowtham