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;i Y_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;i Y_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); }