📄 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 <stdio.h>
#include <stdlib.h>
#include <std.h>
/* ======================================================================== */
/* CSL includes */
/* ======================================================================== */
#include <csl.h>
#include <csl_irq.h>
#include <csl_dat.h>
#include <csl_cache.h>
#include <csl_legacy.h>
/* ======================================================================== */
/* 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<height;i++){
id = DAT_copy(((IMG *)in)->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<height >> 1; i++) {
Cb_in_int = (unsigned char *)dstr_get(&din_Cb);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -