There are many descriptions about YUV4: 2: 2 to YUV4: 2: 0 on the network, but most of them are about the principle and there is no practical practice, this article provides the code tested on ti davinci DM6446 for your reference and learning. At the same time, I hope you can give us some advice. This method is applicable to DSP series such as TI, DM643x, and DM644x. The previous image collection formats are generally YCbCr (YUV4: 2: 2). However, many video applications require YUV4: 2: 2. Convert to YUV4: 2: 0 format, such as jpeg, MPEG4, H. 264, etc. On DM643x and DM644x, TI adopts the EDMA3 Method for conversion. That is another method. Here we will introduce the general practice in DM6441 (513 MHz) 7.5 ms for processing 640x480, and you can try it again. /*************************************** * *******/The palth format is used as an example, here, YCbCr (YUV4: 2: 2) is arranged in the following ways: U0, 0 Y0, 0 V0, 0 Y U0, 1 Y0, 2 V0, 1 Y 0, 3 ...... u0, 359 Y0, 718 V0, 359 Y 0,719 .............................. u575, 0 Y575, 0 V575, 0 Y 575,1 ........... u575, 359 Y575, 718 V575, 359 Y 575,719650) this. width = 650; "onclick = 'window. open ("http://blog.51cto.com/viewpic.php? Refimg = "+ this. src) 'style = "width: 471px; height: 320px "height =" 320 "alt =" NTSC "D1 YUV422 pan fry" src = "http://www.bkjia.com/uploads/allimg/131228/1RU94507-0.jpg" width = "400" border = "0"/> We want to convert it to the YUV4: 2: 0 format: 650) this. width = 650; "onclick = 'window. open (" http://blog.51cto.com/viewpic.php? Refimg = "+ this. src) 'style = "width: 445px; height: 500px "height =" 500 "alt =" NTSC "D1 YUV420 pan fry" src = "http://www.bkjia.com/uploads/allimg/131228/1RU94R7-1.jpg" width = "420" border = "0"/> /* Definition of video input format */# define PAL 1/* paled CCD camera image acquisition */# define NTSC 0/* ntsc ccd camera image acquisition */# define CMOS 0/ * CMOS camera image acquisition */# if (1 = PAL) # define ORG_IMG_WIDTH 720/* D1 format */# define ORG_IMG_HEIGHT 576 # elif (1 = NTSC) # define ORG_IMG_WIDTH 720/* D1 format */# define ORG_IMG_HEIGHT 480 # elif (1 = CMOS) # define ORG_IMG_WIDTH 640/* VGA format */# define ORG_IMG_HEIGHT 480 # endif encoding * unsigned char YCbCr_buf)/* YCbCr_buf points to the YUV4: 2: 2 space */{unsigned int m0, m1, m2, m3, x, y;
Unsigned int tmp, tmp0, tmp1, tmp2;
Tmp = (unsigned int) YCbCr_buf;/* BUF for D1, CIF, QCIF, VGA, and QVGA must be 4-byte alignment, so it is also possible to define unsigned int here, of course, you can also use pointers */
Tmp0 = (unsigned int) Y_buf;
For (y = 0; y <ORG_IMG_HEIGHT; y ++)
{
For (x = 0; x <(ORG_IMG_WIDTH> 1); x + = 4)
{
M0 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <1) + (x <2);/m1 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <1) + (x + 1) <2 ));
M2 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <1) + (x + 2) <2 ));
M3 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <1) + (x + 3) <2 ));
* (Unsigned short *) (tmp0 + y * ORG_IMG_WIDTH + (x <1) = (unsigned short) (m0> 16) & 0xFF00) | (m0> 8) & 0x00FF ));
* (Unsigned short *) (tmp0 + y * ORG_IMG_WIDTH + (x + 1) <1) = (unsigned short) (m1> 16) & 0xFF00) | (m1> 8) & 0x00FF ));
* (Unsigned short *) (tmp0 + y * ORG_IMG_WIDTH + (x + 2) <1) = (unsigned short) (m2> 16) & 0xFF00) | (m2> 8) & 0x00FF ));
* (Unsigned short *) (tmp0 + y * RG_IMG_WIDTH + (x + 3) <1) = (unsigned short) (m3> 16) & 0xFF00) | (m3> 8) & 0x00FF ));
}
}
Tmp1 = (unsigned int) U_buf;
Tmp2 = (unsigned int) V_buf;
For (y = 0; y <(ORG_IMG_HEIGHT> 1); y ++)
{
For (x = 0; x <(ORG_IMG_WIDTH> 1); x + = 4)
{
M0 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <2) + (x <2 ));
M1 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <2) + (x + 1) <2 ));
M2 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <2) + (x + 2) <2 ));
M3 = * (unsigned int *) (tmp + y * (ORG_IMG_WIDTH <2) + (x + 3) <2 ));
* (Unsigned char *) (tmp1 + y * (ORG_IMG_WIDTH> 1) + x) = (unsigned char) m0;
* (Unsigned char *) (tmp2 + y * (ORG_IMG_WIDTH> 1) + x) = (unsigned char) (m0> 16 );
* (Unsigned char *) (tmp1 + y * (ORG_IMG_WIDTH> 1) + x + 1) = (unsigned char) m1;
* (Unsigned char *) (tmp2 + y * (ORG_IMG_WIDTH> 1) + x + 1) = (unsigned char) (m1> 16 );
* (Unsigned char *) (tmp1 + y * (ORG_IMG_WIDTH> 1) + x + 2) = (unsigned char) m2;
* (Unsigned char *) (tmp2 + y * (ORG_IMG_WIDTH> 1) + x + 2) = (unsigned char) (m2> 16 );
* (Unsigned char *) (tmp1 + y * (ORG_IMG_WIDTH> 1) + x + 3) = (unsigned char) m3;
* (Unsigned char *) (tmp2 + y * (ORG_IMG_WIDTH> 1) + x + 3) = (unsigned char) (m3> 16 );
}
} Above code comment: DSP optimization principle, can shift, do not multiply; Can int READ memory, do not use char READ memory, because C64, the C64 + DSP Memory read instruction requires four clock cycles. The cycle can be a multiple of four. It is best to split up four operations to form Pipeline operations. Of course, there is no if in the loop, break and other statements. In addition, you can use a program with higher efficiency on the DM643 and DM643. # Include <csl. h>
# Include <csl_dat.h>
# Include <csl_cache.h> # pragma DATA_SECTION (int_mem_temp, ". img_buf");/* define. img_buf to L2RAM */
# Pragma DATA_ALIGN (int_mem_temp, 128 );
Unsigned char int_mem_temp [720]; void yuv422to420 (char * frameIn [], char * frm_out [],
Int width, int height)
{
Char * pSrcY = frameIn [0];
Char * pSrcU = frameIn [1];
Char * pSrcV = frameIn [2]; char * pDestY = frm_out [0];
Char * pDestU = frm_out [1];
Char * pDestV = frm_out [2]; unsigned int id;
Unsigned int I; for (I = 0; I {
Id = DAT_copy (pSrcY + (I * 720), int_mem_temp, 720 );
Id = DAT_copy (int_mem_temp, pDestY + (I * 720), 720 );
DAT_wait (id );
} For (I = 0; I <(height> 1); I ++)
{
Id = DAT_copy (pSrcU + (I * 720), int_mem_temp, 360 );
Id = DAT_copy (int_mem_temp, pDestU + (I * 360), 360 );
DAT_wait (id );
} For (I = 0; I <(height> 1); I ++)
{
Id = DAT_copy (pSrcV + (I * 720), int_mem_temp, 360 );
Id = DAT_copy (int_mem_temp, pDestV + (I * 360), 360 );
DAT_wait (id );
} Return;
} Void yuv420to422 (char * frameIn [], char * frm_out [],
Int width, int height)
{
Char * pSrcY = frameIn [0];
Char * pSrcU = frameIn [1];
Char * pSrcV = frameIn [2]; char * pDestY = frm_out [0];
Char * pDestU = frm_out [1];
Char * pDestV = frm_out [2]; unsigned int id;
Unsigned int I; for (I = 0; I {
Id = DAT_copy (pSrcY + (I * 720), int_mem_temp, 720 );
Id = DAT_copy (int_mem_temp, pDestY + (I * 720), 720 );
DAT_wait (id );
} For (I = 0; I <(height> 1); I ++)
{
Id = DAT_copy (pSrcU + (I * 360), int_mem_temp, 360 );
Id = DAT_copy (int_mem_temp, pDestU + (2 * I) * 360), 360 );
Id = DAT_copy (int_mem_temp, pDestU + (2 * I + 1) * 360), 360 );
DAT_wait (id );
} For (I = 0; I <(height> 1); I ++)
{
Id = DAT_copy (pSrcV + (I * 360), int_mem_temp, 360 );
Id = DAT_copy (int_mem_temp, pDestV + (2 * I) * 360), 360 );
Id = DAT_copy (int_mem_temp, pDestV + (2 * I + 1) * 360), 360 );
DAT_wait (id );
} Return;
}