📄 videoinedgedetection_buffers.c
字号:
SobelFlag.SobelInBufID = 1; // start loading luma values to Sobel_In_Buf0
SobelFlag.SobelOutBufID = 1; // start loading processed luma values to Sobel_Out_Buf0
SobelFlag.SobelInBuf0Done = TRUE; // Sobel_In_Buf0 is ready to get a block of luma
SobelFlag.SobelInBuf1Done = TRUE; // Sobel_In_Buf1 is ready to get a block of luma
SobelFlag.SobelInMDMALock = FALSE; // Unlock Video In buffer to Sobel In buffer MDMA stream
SobelFlag.SobelOutBuf0Done = FALSE; // Mark as both Sobel out buffers are ready to get edge detected data
SobelFlag.SobelOutBuf1Done = FALSE;
SobelFlag.SobelOutMDMALock = TRUE; // Lock Sobel out to Video out MDMA as no edge detected data is available to process
SobelFlag.InitSobelOut = FALSE; // Sobel Out function not initialised
SobelInBlockCount = 0; // sobel buf sized block (Block 0 of Active frame 1) will be read from Video in bufx
SobelInColumnBlockCount = 1; // Processing Column 1 sobel blocks
SobelOutBlockCount = 0; // Block 0 of Active frame 1 - will be copied to Video_Out_Bifx after edge detection
SobelOutColumnBlockCount = 1; // Processing Column 1 sobel blocks
return;
}
/*********************************************************************
Function: MDMA_SobelIn
Description: MDMA Sobel In buffer update - callback routine
*********************************************************************/
section ("App_Code_L1")
void MDMA_SobelIn(void)
{
/*******************************************
video in buffer to sobel in buffer stream
*******************************************/
/**** Sobel In stream destination buffer config ****/
// Check previously used Sobel In buffer ID
// If the previous buffer was Sobel_In_Buf1, then Sobel_In_Buf0 should be used next
if (SobelFlag.SobelInBufID)
{
// check if Sobel_In_Buf0 is ready
if (SobelFlag.SobelInBuf0Done)
{
// then prepare the sobel in buf 0 with video in bufx luma values
MDMA_Sobel_In_Des.StartAddress = (void *) (&Sobel_In_Buf0[0]);
// Sobel_In_Buf0 will be loaded with luma values
SobelFlag.SobelInBufID = 0;
}
else // return as Sobel_In_Buf0 is not ready yet
return;
}
else // Previous buffer was Sobel_In_Buf0. So Sobel_In_Buf1 should be used next
{
if (SobelFlag.SobelInBuf1Done) // check if Sobel_In_Buf1 is ready
{
// then load sobel in buf 1 with video in luma values
MDMA_Sobel_In_Des.StartAddress = (void *) (&Sobel_In_Buf1[0]);
// Sobel_In_Buf1 will be loaded with luma values
SobelFlag.SobelInBufID = 1;
}
else // return as Sobel_In_Buf1 is not ready yet
return;
}
++SobelInBlockCount; // next sobel block number to build
// Check if this is the first sobel block
// if yes, load the pVideoInBuf value
if (tpVideoInBuf == NULL)
{
tpVideoInBuf = pVideoInBuf;
SobelInBlockCount = 0; // Sobel is processing block 0
}
// Check if Active Field 1 is done. if so, process Video_In_Bufx Active field 2
else if (!(SobelInBlockCount % SobelBlockCount))
{
// pVideoInBuf points to first luma value minus 2 of Video_In_Bufx Active Field1
// with sobel algorithm offset of extra 2 rows per block & 2 columns per row
// update pVideoInBuf & temp pointer to point to first luma value of the above buffer's Active Field2
// with sobel algorithm offset of extra 2 rows per block & 2 columns per row
pVideoInBuf = (pVideoInBuf + (Field2Skip - Field1Skip));
tpVideoInBuf = pVideoInBuf;
SobelInColumnBlockCount = 1; // move to column 1 of sobel block
}
else if (!(SobelInBlockCount % SobelFieldBlocks)) // move to the next column block
{
// pVideoInBuf always to first luma value of Video_In_Bufx Active Field1 or Field2
// with sobel algorithm offset of extra 2 rows per block & 2 columns per row
tpVideoInBuf = (pVideoInBuf + (SOBEL_COLUMN_SIZE * 2 * SobelInColumnBlockCount));
SobelInColumnBlockCount++; // move to next column in the sobel block
}
else // move to next row in sobel block
{
tpVideoInBuf = (tpVideoInBuf + (DataPerLine * SobelRowSize));
}
// Load the Source start address
MDMA_Sobel_In_Src.StartAddress = (void *) tpVideoInBuf;
// lock video in to sobel in MDMA until this transfer is finished
SobelFlag.SobelInMDMALock = TRUE;
// Start MDMA 2D copy (video in buffer to sobel in buffer stream)
// MDMA stream handle, 2D destination config, 2D source config, Element width (1 byte), Callback function
ezErrorCheck(adi_dma_MemoryCopy2D (MDMA_Handle_Stream0,&MDMA_Sobel_In_Des,&MDMA_Sobel_In_Src,1,MDMA_Callback0));
return;
}
/*********************************************************************
Function: MDMA_SobelOut
Description: MDMA Sobel Out buffer update - callback routine
*********************************************************************/
section ("App_Code_L1")
void MDMA_SobelOut()
{
if (SystemFlag.SobelDone) // Sobel conversion of Video In Bufx is done. wait until next Video In Buf is ready
return;
/*******************************************
Sobel out buffer to video out buffer stream
*******************************************/
/**** Sobel Out stream Source buffer config ****/
// Start address - init to point the first VALID location in Sobel_Out_Buf1
// always first and last row in a sobel out buffer is invalid
// always first and last column in each sobel out buffer row is invalid
// Check previously used Sobel Out buffer ID
if (SobelFlag.SobelOutBufID) // If the previous buffer was Sobel_Out_Buf1, then Sobel_Out_Buf0 should be used next
{
if (SobelFlag.SobelOutBuf0Done) // check if Sobel_Out_Buf0 is ready
{
// Sobel_Out_Buf0 has sobel edge detected values
MDMA_Sobel_Out_Src.StartAddress = (void *) (&Sobel_Out_Buf0[0] + SOBEL_COLUMN_SIZE + SOBEL_OFFSET + 1);
// Sobel_Out_Buf0 will be copied to Video_Out_Buf
SobelFlag.SobelOutBufID = 0;
}
else
return; // return as Sobel_Out_Buf1 is not ready yet
}
else // Previous buffer was Sobel_Out_Buf0. So Sobel_Out_Buf1 should be used next
{
if (SobelFlag.SobelOutBuf1Done) // check if Sobel_Out_Buf1 is ready
{
// Sobel_Out_Buf1 has sobel edge detected values
MDMA_Sobel_Out_Src.StartAddress = (void *) (&Sobel_Out_Buf1[0] + SOBEL_COLUMN_SIZE + SOBEL_OFFSET + 1);
SobelFlag.SobelOutBufID = 1; // Sobel_Out_Buf1 will be copied to Video_Out_Buf
}
else
return; // return as Sobel_Out_Buf0 is not ready yet
}
++SobelOutBlockCount; // next sobel block number to build
// Check if this is the first sobel block
// if yes, load the pVideoOutBuf value (pVideoOutBuf points to first luma value of Video_In_Bufx Active Field1)
if (tpVideoOutBuf == NULL)
{
tpVideoOutBuf = pVideoOutBuf;
SobelOutBlockCount = 0; // Sobel is processing block 0
}
// Check if Active Field 1 is done.
else if (!(SobelOutBlockCount % SobelBlockCount)) // if yes, process Video_In_Bufx Active field 2
{
// pVideoOutBuf is pointing to first luma value of Video_In_Bufx Active Field1
// update pVideoOutBuf & temp pointer to point to first luma value of the above buffer's Active Field2
pVideoOutBuf = (pVideoOutBuf + (Field2Skip - Field1Skip));
tpVideoOutBuf = pVideoOutBuf;
SobelOutColumnBlockCount = 1; // move to column 1 of sobel block
}
else if (!(SobelOutBlockCount % SobelFieldBlocks)) // move to the next column block
{
// pVideoOutBuf points to first luma value of Video_In_Bufx Active Field1 or Field2
tpVideoOutBuf = (pVideoOutBuf + (SOBEL_COLUMN_SIZE * 2 * SobelOutColumnBlockCount));
SobelOutColumnBlockCount++; // move to next column in the sobel block
}
else // move to next row in sobel block
{
tpVideoOutBuf = (tpVideoOutBuf + (DataPerLine * SobelRowSize));
}
// completed processing whole video in bufx frame
if ((SobelOutBlockCount+1) >= (SobelBlockCount * 2))
{
// Sobel conversion of Video_In_Bufx is done. wait until next Video_In_Bufx is ready
SystemFlag.SobelDone = TRUE;
}
// Load the Destination start address
MDMA_Sobel_Out_Des.StartAddress = (void *) tpVideoOutBuf;
// lock sobel out to video out MDMA until this transfer is finished
SobelFlag.SobelOutMDMALock = TRUE;
// Start MDMA 2D copy (Sobel Out Bufx to Video Out Bufx data stream)
// MDMA stream handle, 2D destination config, 2D source config, Element width (1 byte), Callback function
ezErrorCheck(adi_dma_MemoryCopy2D (MDMA_Handle_Stream1,&MDMA_Sobel_Out_Des,&MDMA_Sobel_Out_Src,1,MDMA_Callback1));
return;
}
/*********************************************************************
Function: do_SobelEdgeDetection
Description: Performs sobel edge detection on incoming video
and displays the result in a video monitor
*********************************************************************/
section ("App_Code_L1")
void do_SobelEdgeDetection (void)
{
// start next sobel conversion only if this falg is cleared
if (!SystemFlag.SobelDone)
{
// check if previous video in to sobel in streaming is done
if (!SobelFlag.SobelInMDMALock)
{
// load next set of luma values from Video_In_Bufx to Sobel_In_Bufx
MDMA_SobelIn ();
}
// Check if Sobel_In_Buf0 & Sobel_Out_Buf0 are ready
if ((!SobelFlag.SobelInBuf0Done) && (!SobelFlag.SobelOutBuf0Done))
{
// if so, start sobel conversion with sobel in/out bufs 0
// call Sobel edge detection routine
// Sobel threshold empirically set to 100
sobel_fast(&Sobel_In_Buf0[0], (SobelRowSize+SOBEL_OFFSET), (SOBEL_COLUMN_SIZE+SOBEL_OFFSET), &Sobel_Out_Buf0[0], 2);
// Sobel_Out_Buf0 has Sobel out values to copy to Video_Out_Buf
SobelFlag.SobelOutBuf0Done = TRUE;
// Sobel_In_Buf0 is ready to get next block of luma
SobelFlag.SobelInBuf0Done = TRUE;
}
// Check if Sobel_In_Buf1 & Sobel_Out_Buf1 are ready
else if ((!SobelFlag.SobelInBuf1Done) && (!SobelFlag.SobelOutBuf1Done))
{
// if so, start sobel conversion with sobel in/out bufs 1
// call Sobel edge detection routine
// Sobel threshold empirically set to 100
sobel_fast(&Sobel_In_Buf1[0], (SobelRowSize+SOBEL_OFFSET), (SOBEL_COLUMN_SIZE+SOBEL_OFFSET), &Sobel_Out_Buf1[0]);
// Sobel_Out_Buf1 has Sobel out values to copy to Video_Out_Buf
SobelFlag.SobelOutBuf1Done = TRUE;
// Sobel_In_Buf1 is ready to get next block of luma
SobelFlag.SobelInBuf1Done = TRUE;
}
// check if previous sobel out to video out streaming is done
if (!SobelFlag.SobelOutMDMALock)
{
// start Sobel_Out_Bufx to Video_Out_Buf streaming
MDMA_SobelOut();
}
}
return;
}
/*****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -