⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 videoinedgedetection_buffers.c

📁 这个是balckfin533/561的视频输入和输出的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	
    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 + -