www.pudn.com > SobelEdge_all_2.rar > chroma_resampling.c


/* ======================================================================== */ 
/* NAME                                                                     */ 
/*  chroma_resampling.c 										            */ 
/*                                                                          */ 
/*	DESCRIPTION																*/ 
/* This file contains chroma resampling routines for use with the ZENO      */ 
/* Video Port.                                                              */ 
/* All these routines have been written using the DMA streaming (dstr)      */ 
/* interface. Specifically, it contains the following APIs:                 */ 
/* YUV422to420v() - This routine performs the vertical part of chroma       */ 
/*                  resampling in going from 4:2:2 to 4:2:0                 */ 
/* YUV420to422v() - This routine performs the vertical part of chroma       */ 
/*                  resampling in going from 4:2:0 to 4:2:2                 */ 
/* ------------------------------------------------------------------------ */ 
/*            Copyright (c) 2002 Texas Instruments, Incorporated.           */ 
/*                           All Rights Reserved.                           */ 
/* ======================================================================== */ 
 
/* ======================================================================== */ 
/* basic header includes                                                    */ 
/* ======================================================================== */ 
#include  
#include  
#include  
 
/* ======================================================================== */ 
/* CSL includes                                                             */ 
/* ======================================================================== */ 
#include  
#include  
#include  
#include  
#include  
 
/* ======================================================================== */ 
/* include files for DMA streaming and scaling kernel that performs         */ 
/* vertical chroma resampling                                               */ 
/* ======================================================================== */ 
#include "dstr_2d.h" 
#include "scale_v2_h.h" 
 
/* ======================================================================== */ 
/* Image and scratch buffer structures for pre-post processing operations   */ 
/* ======================================================================== */ 
 
typedef struct { 
					unsigned char *Y_data; 
					unsigned char *Cb_data; 
					unsigned char *Cr_data; 
				} IMG; 
typedef struct { 
					unsigned char *in_data; 
					int  size; 
				}SCRATCH;			 
					 
 
 
 
/* ======================================================================== */ 
/* YUV422to420v() - vertical chroma resampling of source                    */ 
/* INTERFACE:                                                               */ 
/* void YUV422to420v(                                                       */ 
/*                  void *in,                                               */ 
/*                  void *out,                                              */ 
/*                  int width,                                              */ 
/*                  int height,                                             */ 
/*                  void *scratch                                           */ 
/*                  );                                                      */ 
/* RETURN VALUE: None                                                       */ 
/* PARAMETERS:                                                              */ 
/* in  - pointer to input data(planar Y:Cb:Cr 4:2:2 format)                 */ 
/* out - pointer to output data (planar Y:Cb:Cr 4:2:0 format)               */ 
/* width - pixels per line of source luma                                   */ 
/* height - number of lines of source luma                                  */ 
/* scratch - pointer to scratch buffer in DSP's internal memory(used by     */ 
/*           dstr interface for DMA operation)                              */ 
/* ======================================================================== */ 
 
void YUV422to420v(void *in,void *out,int width,int height,void *scratch) { 
	 
	int i,err_code; 
	unsigned int id; 
	 
	/* ==================================================================== */ 
	/* External Buffer pointers                                             */ 
	/* ==================================================================== */ 
	unsigned char *Cr_in,*Cb_in; 
	unsigned char *Cr_out,*Cb_out; 
	 
	/* ==================================================================== */ 
	/* Internal scratch pointer                                             */ 
	/* ==================================================================== */ 
	unsigned char *int_mem; 
	 
	/* ==================================================================== */ 
	/* dma stream objects                                                   */ 
	/* ==================================================================== */ 
	dstr_t din_Cr,din_Cb,dout_Cr,dout_Cb; 
	 
	 
	/* ==================================================================== */ 
	/* Internal Buffer pointers                                             */ 
	/* ==================================================================== */ 
	unsigned char *Cb_in_int,*Cr_in_int,*Cb_out_int,*Cr_out_int;	 
	unsigned char *Cb_in_sc,*Cr_in_sc,*Cb_out_sc,*Cr_out_sc; 
	 
	 
	/* ==================================================================== */ 
	/* get pointers to input and output data(in external memory)            */ 
	/* ==================================================================== */ 
	Cr_in = ((IMG *)in)->Cr_data; 
	Cb_in = ((IMG *)in)->Cb_data; 
	 
	Cr_out = ((IMG *)out)->Cr_data; 
	Cb_out = ((IMG *)out)->Cb_data;	 
	 
	/* ==================================================================== */ 
	/* setup the internal scratch(work) buffers                             */ 
	/* ==================================================================== */ 
	int_mem = ((SCRATCH *)scratch)->in_data; 
	Cb_in_sc  = int_mem; 
	Cr_in_sc  = int_mem + 4  * width; 
	Cb_out_sc = int_mem + 8  * width; 
	Cr_out_sc = int_mem + 10  * width; 
	 
	/* ==================================================================== */ 
	/* The luminance data is not processed at all                           */ 
	/* Check if the user passed the same buffer pointers for input and      */ 
	/* output Y, else copy the data from input to output buffer             */ 
	/* ==================================================================== */ 
	 
	if(((IMG *)in)->Y_data != ((IMG *)out)->Y_data){ 
	    for(i=0;iY_data +i*width,int_mem,width);	 
	        DAT_wait(id);	     
	        id = DAT_copy(int_mem,((IMG *)out)->Y_data +i*width,width);	 
	    } 
	} 
	 
	DAT_wait(id); 
	 
	 
	/* ==================================================================== */ 
	/* Set up the DMA streams                                               */ 
	/* ==================================================================== */ 
	 
	 
	/* ==================================================================== */ 
	/* open input chroma streams with the following parameters:             */ 
	/* size of external buffer -->  (width/2)*height (4:2:2 data)           */ 
	/* size of internal buffer -->  width*4 (work buffer needs to be atleast*/ 
	/*                              width*2 but we overallocate here)       */	 
	/* size of each get        -->  width ( bring in two lines of chroma,   */	 
	/*                               each width/2 pixels)                   */  
	/* number of gets          -->  1                                       */ 
	/* external pointer stride -->  width   (stride by an amount equal to   */ 
	/*                              size of each get)                       */ 
	/* window size             -->  1 (double buffering)                    */	 
	/* ==================================================================== */ 
	err_code = dstr_open(&din_Cb, 
						 Cb_in, 
						 width * height>> 1, 
						 Cb_in_sc, 
					 	 width * 4, 
						 width, 
					 	 1, 
					  	 width, 
						 1, 
					  	 DSTR_INPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
    err_code = dstr_open(&din_Cr, 
						 Cr_in, 
						 width * height>> 1, 
						 Cr_in_sc, 
					 	 width * 4, 
						 width, 
					 	 1, 
					  	 width, 
						 1, 
					  	 DSTR_INPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif		 
     
	/* ==================================================================== */ 
	/* open output chroma streams with the following parameters:            */ 
	/* size of external buffer -->  (width/2)*(height/2) (4:2:0 data)       */ 
	/* size of internal buffer -->  width (work buffer needs to be atleast  */ 
	/*                              twice the size of actual data sent out) */	 
	/* size of each put        -->  width/2 ( send out one line of chroma,  */	 
	/*                               of width/2 pixels)                     */  
	/* number of puts          -->  1                                       */ 
	/* external pointer stride -->  width/2  (stride by an amount equal to  */ 
	/*                              size of each put)                       */ 
	/* window size             -->  1 (double buffering)                    */	 
	/* ==================================================================== */ 
    err_code = dstr_open(&dout_Cb, 
						 Cb_out, 
						 width * height >> 2, 
						 Cb_out_sc, 
					 	 width , 
						 width >> 1, 
					 	 1, 
					  	 width >> 1, 
						 1, 
					  	 DSTR_OUTPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
     
    err_code = dstr_open(&dout_Cr, 
						 Cr_out, 
						 width * height >> 2, 
						 Cr_out_sc, 
					 	 width, 
						 width >> 1, 
					 	 1, 
					  	 width >> 1, 
						 1, 
					  	 DSTR_OUTPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
     
     
	/* ==================================================================== */ 
	/* Data processing loop:                                                */ 
	/*                                                                      */ 
	/* Bring in data from external memory                                   */ 
	/*                                                                      */ 
	/* Use vertical half scaling kernel on chroma data in internal memory   */ 
	/*                                                                      */ 
	/* Send data back to external memory                                    */	 
	/* ==================================================================== */ 
 
	for(i=0; i> 1; i++) { 
			 
		Cb_in_int  = (unsigned char *)dstr_get(&din_Cb); 
		Cr_in_int  = (unsigned char *)dstr_get(&din_Cr); 
		 
		Cb_out_int = (unsigned char *)dstr_put(&dout_Cb); 
		Cr_out_int = (unsigned char *)dstr_put(&dout_Cr); 
		 
		scale_v2_cn(Cb_in_int,width>>1,width>>1,2,Cb_out_int); 
		scale_v2_cn(Cr_in_int,width>>1,width>>1,2,Cr_out_int); 
		 
		 
	} 
	 
	/* ==================================================================== */ 
	/* DMA out the last lines                                               */ 
	/* ==================================================================== */ 
    dstr_put(&dout_Cb); 
	dstr_put(&dout_Cr); 
	 
	/* ==================================================================== */ 
	/* close the DMA streams                                                */ 
	/* ==================================================================== */ 
	dstr_close(&din_Cb); 
	dstr_close(&din_Cr); 
	dstr_close(&dout_Cb); 
	dstr_close(&dout_Cr); 
	 
} 
 
 
/* ======================================================================== */ 
/* YUV420to422v() - vertical chroma resampling of source                    */ 
/* INTERFACE:                                                               */ 
/* void YUV420to422v(                                                       */ 
/*                  void *in,                                               */ 
/*                  void *out,                                              */ 
/*                  int width,                                              */ 
/*                  int height,                                             */ 
/*                  void *scratch                                           */ 
/*                  );                                                      */ 
/* RETURN VALUE: None                                                       */ 
/* PARAMETERS:                                                              */ 
/* in  - pointer to input data(planar Y:Cb:Cr 4:2:0 format)                 */ 
/* out - pointer to output data (planar Y:Cb:Cr 4:2:2 format)               */ 
/* width - pixels per line of source luma                                   */ 
/* height - number of lines of source luma                                  */ 
/* scratch - pointer to scratch buffer in DSP's internal memory(used by     */ 
/*           dstr interface for DMA operation)                              */ 
/* ======================================================================== */ 
void YUV420to422v(void *in,void *out,int width,int height,void *scratch) { 
	 
	unsigned int id; 
	int i,err_code; 
	 
	/* ==================================================================== */ 
	/* External Buffer pointers                                             */ 
	/* ==================================================================== */ 
	unsigned char *Cr_in,*Cb_in; 
	unsigned char *Cr_out,*Cb_out; 
	 
	/* ==================================================================== */ 
	/* Internal scratch pointer                                             */ 
	/* ==================================================================== */ 
	unsigned char *int_mem; 
	 
	/* ==================================================================== */ 
	/* dma stream objects                                                   */ 
	/* ==================================================================== */ 
	dstr_t din_Cr,din_Cb,dout_Cr,dout_Cb; 
	 
	/* ==================================================================== */ 
	/* Internal Buffer/scratch pointers                                     */ 
	/* ==================================================================== */ 
	unsigned char *Cb_in_int,*Cr_in_int,*Cb_out_int,*Cr_out_int;		 
	unsigned char *Cb_in_sc,*Cr_in_sc,*Cb_out_sc,*Cr_out_sc;	 
	 
	/* ==================================================================== */ 
    /* get pointers to input and output data(in external memory)            */ 
    /* ==================================================================== */ 
	 
	Cr_in = ((IMG *)in)->Cr_data; 
	Cb_in = ((IMG *)in)->Cb_data; 
	 
	 
	// fixed the bug : color mismatch   
	Cb_out = ((IMG *)out)->Cr_data; 
	Cr_out = ((IMG *)out)->Cb_data;	 
	 
	/* ==================================================================== */ 
	/* The luminance data is not processed at all                           */ 
	/* Check if the user passed the same buffer pointers for input and      */ 
	/* output Y, else copy the data from input to output buffer             */ 
	/* ==================================================================== */	 
	 
	if(((IMG *)in)->Y_data != ((IMG *)out)->Y_data){ 
	     for(i=0;iY_data +i*width,int_mem,width);	 
	        DAT_wait(id);	     
	        id = DAT_copy(int_mem,((IMG *)out)->Y_data +i*width,width);	 
	     } 
	} 
	 
	DAT_wait(id);	 
	 
	 
	/* ==================================================================== */ 
    /* setup the internal scratch buffer                                    */ 
    /* ==================================================================== */ 
	 
	int_mem = ((SCRATCH *)scratch)->in_data; 
	Cb_in_sc  = int_mem; 
	Cr_in_sc  = int_mem + 2  * width; 
	Cb_out_sc = int_mem + 4  * width; 
	Cr_out_sc = int_mem + 8 * width; 
 
    /* ==================================================================== */ 
	/* Set up the DMA streams                                               */ 
	/* ==================================================================== */ 
	 
	 
	/* ==================================================================== */ 
	/* open input chroma streams with the following parameters:             */ 
	/* size of external buffer -->  (width/2)*(height/2) (4:2:0 data)       */ 
	/* size of internal buffer -->  width (twice the actual length of data  */ 
	/*                              brought in each time)                   */ 
	/* size of each get        -->  width/2   (bring in one line of chroma) */ 
	/* number of gets          -->  1                                       */ 
	/* external pointer stride -->  width/2   (stride by an amount equal to */ 
	/*                              size of each get)                       */ 
	/* window size             -->  1 (double buffering)                    */	 
	/* ==================================================================== */ 
	err_code = dstr_open(&din_Cb, 
						 Cb_in, 
						 width * height >> 2, 
						 Cb_in_sc, 
					 	 width, 
						 width>>1, 
					 	 1, 
					  	 width>>1, 
						 1, 
					  	 DSTR_INPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
    err_code = dstr_open(&din_Cr, 
						 Cr_in, 
						 width * height >> 2, 
						 Cr_in_sc, 
					 	 width, 
						 width>>1, 
					 	 1, 
					  	 width>>1, 
						 1, 
					  	 DSTR_INPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif		 
     
	/* ==================================================================== */ 
	/* open output chroma streams with the following parameters:            */ 
	/* size of external buffer -->  (width/2)*(height) (4:2:2 data)         */ 
	/* size of internal buffer -->  width*2 (twice the actual length of data*/ 
	/*                              sent out  each time)                    */ 
	/* size of each put        -->  width   (send out two lines of chroma   */ 
	/*                              each time of width/2 pixels)            */ 
	/* number of puts          -->  1                                       */ 
	/* external pointer stride -->  width   (stride by an amount equal to   */ 
	/*                              size of each put)                       */ 
	/* window size             -->  1 (double buffering)                    */	 
	/* ==================================================================== */ 
    err_code = dstr_open(&dout_Cb, 
						 Cb_out, 
						 width * height >> 1, 
						 Cb_out_sc, 
					 	 width * 2, 
						 width, 
					 	 1, 
					  	 width, 
						 1, 
					  	 DSTR_OUTPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
     
    err_code = dstr_open(&dout_Cr, 
						 Cr_out, 
						 width * height >> 1, 
						 Cr_out_sc, 
					 	 width * 2 , 
						 width, 
					 	 1, 
					  	 width, 
						 1, 
					  	 DSTR_OUTPUT); 
	#ifdef DEBUG                      
    if(err_code) 
    { 
        LOG_printf(&trace, "error opening Cb buffer:%d \n",  
                   err_code); 
    } 
    #endif 
 
 
    /* ==================================================================== */ 
	/* Data processing loop:                                                */ 
	/*                                                                      */ 
	/* Bring in data from external memory                                   */ 
	/*                                                                      */ 
	/* Use memcpy on internal memory buffers to double the chroma lines     */ 
	/*                                                                      */ 
	/* Send data back to external memory                                    */	 
	/* ==================================================================== */ 
	 
	for(i=0; i> 1; i++) {	 
		 
		Cb_in_int  = (unsigned char *)dstr_get(&din_Cb); 
		Cr_in_int  = (unsigned char *)dstr_get(&din_Cr); 
		 
		Cb_out_int = (unsigned char *)dstr_put(&dout_Cb); 
		Cr_out_int = (unsigned char *)dstr_put(&dout_Cr); 
		 
		memcpy(Cb_out_int,Cb_in_int,width>>1); 
		memcpy(Cb_out_int+(width>>1),Cb_in_int,width>>1); 
		memcpy(Cr_out_int,Cr_in_int,width>>1); 
		memcpy(Cr_out_int+(width>>1),Cr_in_int,width>>1); 
		 
	} 
		 
		 
	/* ==================================================================== */ 
	/* DMA out the last lines                                               */ 
	/* ==================================================================== */	 
    dstr_put(&dout_Cb); 
	dstr_put(&dout_Cr); 
	 
	/* ==================================================================== */ 
	/* close the DMA streams                                                */ 
	/* ==================================================================== */ 
	dstr_close(&din_Cb); 
	dstr_close(&din_Cr); 
	dstr_close(&dout_Cb); 
	dstr_close(&dout_Cr); 
}