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

📄 vivot.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的各种滤波器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 1995,2000 TriMedia Technologies Inc.
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 *  Module name              : vivot.c    1.51
 *
 *  Last update              : 21:41:02 - 99/07/19
 *
 *  Description              :
 *
 *  Revision                 :
 *
 */

/**************************************************************************
 *                                                                        *
 * Please ignore this, if you have tm1s1.1 or better.                     *
 *                                                                        *
 *  ======>>>>>>>>>   IMPORTANT NOTICE   <<<<<<<<<<<<<==========          *
 * If you have tm1s1.0 or older version of chip, please contact  Philips  *
 * TriMedia to exchange to newer version of chip.                         *
 *                                                                        *
 * The tm1s1.0 or older version chips contain video-in hardware bugs      *
 * # 3016, 21217, 21336, 21390, and require extensive workaround.  We     *
 * are no longer supporting the software workaround.                      *
 *                                                                        *
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <tm1/mmio.h>
#include <ops/custom_defs.h>
#include <tm1/tmVI.h>
#include <tm1/tmVO.h>
#include <tm1/tmICP.h>
#include <tm1/tmAvFormats.h>
#include <tm1/tmVImmio.h>
#include <tm1/tmVOmmio.h>
#include <tm1/tmInterrupts.h>
#include <tm1/tmProcessor.h>
#include <tmlib/tmlibc.h>
#include <tmlib/dprintf.h>
#include <tmlib/AppModel.h>

#if	TBC==1
#include "tbc.h"	
static float  tbcGain =  0;		/* COD 3.21.2000 */
static float tbcPhase = 30;		/* COD 3.21.2000 */
int    tbcDebug = 1;
#endif

#define  VID_RDY_VI             1    /* buffer is ready for vi to use */
#define  VID_RDY_MM             2    /* buffer is ready for mm to use */
#define  VID_RDY_VO             4    /* buffer is ready for vo to use */

#define  NUM_BUF_ENTRIES        4

#define  CACHE_LINE_SIZE        64

typedef struct _videoBuf {    /* video buffer structure example */
    UInt32      Y;            /* buffer pointer for Y */
    UInt32      U;            /* buffer pointer for U */
    UInt32      V;            /* buffer pointer for V */
    UInt32      flag;         /* flags used in buffer management */
}           vBuf, *pvBuf;

static vBuf fullResBuf[NUM_BUF_ENTRIES];
static vBuf cif422Buf[NUM_BUF_ENTRIES];
static vBuf bkBuf[1];
static vBuf genBuf[NUM_BUF_ENTRIES];

static Bool invertField = False;

static Int  viInst;
static viInstanceSetup_t viInstSup;
static viYUVSetup_t viYUVSup;

static Int  voInst;
static voInstanceSetup_t voInstSup;
static voYUVSetup_t voYUVSup;
static voOverlaySetup_t voOverlaySup;

static Int  icpInst;
static icpInstanceSetup_t icpInstSup;
static icpImageColorConversion_t icpImage;

static Int  cifStride = 384;
static Int  cifWidth = 352;
static Int  cifHeight = 240;

static Int  fullStride = 768;
static Int  fullWidth = 720;
static Int  fullHeight = 480;

static Char *Header = "\nTriMedia Video-In to Video-Out "
                      "Example Program Version 2.0\n";

static Int  viNum = 0;
static Int  mmNum = 0;
static Int  voNum = 0;

static Int  yFieldStride = 0;
static Int  uvFieldStride = 0;
static Int  overlayFieldStride = 0;

static Int  yScanWidth = 0;
static Int  uvScanWidth = 0;

static Bool capField = False;
static Bool firstField = False;
static Bool runningOverlay = False;

static Bool endless = False;
static Int  loopCount = 1000;
static volatile Int  voISRCount = 0;

static tmVideoAnalogStandard_t videoStandard = vasNTSC;
static tmVideoAnalogAdapter_t  inAdapterType = vaaCVBS;
static tmVideoAnalogAdapter_t  outAdapterType = vaaCVBS;

static unitSelect_t videoInUnit = unit0;

static void
my_abort(Char * name, Int err)
{
    assert(name != Null);
    fprintf(stderr, "%s failed, error code %x\n", name, err);
    exit(-1);
}

void
_voTestISR()
{
    UInt32 vo_status = MMIO(VO_STATUS);
    Int    votmpNum;

    voISRCount++;

#if TBC==0
    DP(("vo ISR %u %x\n", CYCLES(), vo_status));
#endif
    if (voYTR(vo_status))
        voAckYTR_ACK();
    if (voURUN(vo_status))
        voAckURUN_ACK();
    if (voHBE(vo_status))
        voAckHBE_ACK();
    if (voBUF2EMPTY(vo_status))
        voAckBFR2_ACK();
    if (voBUF1EMPTY(vo_status)) {    /* bfr1 empty */

        if (runningOverlay) {
            if (voFIELD2(vo_status)) {
                /* from f1 to f2 */
                voYUVChangeBuffer(voInst,
                          bkBuf[0].Y + yFieldStride,
                          bkBuf[0].U + uvFieldStride,
                          bkBuf[0].V + uvFieldStride);
                voOverlayChangeBuffer(voInst, 
                                      genBuf[voNum].Y + overlayFieldStride);
            }
            else {
                votmpNum = (voNum + 1) % NUM_BUF_ENTRIES;
                if (genBuf[votmpNum].flag == VID_RDY_VO) {
                    genBuf[voNum].flag = VID_RDY_VI;
                    voNum = votmpNum;
                }
                voYUVChangeBuffer(voInst,
                          bkBuf[0].Y,
                          bkBuf[0].U,
                          bkBuf[0].V);
                voOverlayChangeBuffer(voInst, genBuf[voNum].Y);
            }
        }
        else {
            if (voFIELD2(vo_status)) {
                /* from f1 to f2 */
                voYUVChangeBuffer(voInst,
                    (Char *) genBuf[voNum].Y + yFieldStride,
                    (Char *) genBuf[voNum].U + uvFieldStride,
                    (Char *) genBuf[voNum].V + uvFieldStride);
            }
            else {
                votmpNum = (voNum + 1) % NUM_BUF_ENTRIES;
                if (genBuf[votmpNum].flag == VID_RDY_VO) {
                    genBuf[voNum].flag = VID_RDY_VI;
                    voNum = votmpNum;
                }
                voYUVChangeBuffer(voInst,
                          genBuf[voNum].Y,
                          genBuf[voNum].U,
                          genBuf[voNum].V);
            }
        }
        voAckBFR1_ACK();

        return;
    }
}

void
voTestISR()
{
#pragma TCS_handler
    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_voTestISR, Null);
    AppModel_resume_scheduling();
}


void
_viTestISR()
{
    UInt32 vi_status;
    Int    oddField;
    Int    vitmpNum;
    UInt32 mmioBase;

#if TBC==1 
    {
      tbcAdjust();
      if (!(voTbc.frame % tbcDebug)) 
	DP(("TBC: phase %f -> %f degrees, clock %d hz\n",
	    voTbc.phase, voTbc.skew, tbcClockFreq(MMIO(VO_CLOCK))));
    }
#endif

    if (videoInUnit == unit0)
        mmioBase = VI1_MMIO_BASE;
    else
        mmioBase = VI2_MMIO_BASE;

    vi_status = MMIO(mmioBase + VI_STATUS_OFFSET);

#if TBC==0
    DP(("vi ISR %u %x mmioBase %x\n", CYCLES(), vi_status, mmioBase));
#endif
    oddField = viExtractODD(vi_status);

    /* Should the field ID be inverted? */
    if (invertField)
        oddField = !oddField;

    if ((vi_status & 0x1) == 0) {

        /*
         * This is due to hardware bug 21390, a spurious interrupt
         * may occur. Since we have only enabled capture_enable (0x1)
         * we should not check on threshold_reached (0x2)
         */
        return;
    }
    if (viHBE(vi_status)) {

        /*
         * Highway banmdwidth, VI needs more bandwidth. You can play
         * with the highway arbitration setting
         */
        viAckHBE_ACKM(mmioBase);
        return;
    }

    if (capField) {
        vitmpNum = (viNum + 1) % NUM_BUF_ENTRIES;
        if (oddField & (genBuf[vitmpNum].flag == VID_RDY_VI)) {
            genBuf[viNum].flag = VID_RDY_MM;
            viNum = vitmpNum;
            viYUVChangeBufferM(mmioBase, viInst,
                              genBuf[viNum].Y,
                              genBuf[viNum].U,
                              genBuf[viNum].V);
        }
        viAckCAP_ACKM(mmioBase);

        return;
    }

    if (firstField) {
        firstField = False;

        if (!oddField) {
            /* skip even field to get sync */
            firstField = True;
        }
        else {
            /* always start with odd field */
            viYUVChangeBufferM(mmioBase, viInst,
                              genBuf[viNum].Y + yScanWidth,
                              genBuf[viNum].U + uvScanWidth,
                              genBuf[viNum].V + uvScanWidth);
        }
    }
    else {
        vitmpNum = (viNum + 1) % NUM_BUF_ENTRIES;
        if (genBuf[vitmpNum].flag == VID_RDY_VI) {
            genBuf[viNum].flag = VID_RDY_MM;
            viNum = vitmpNum;
        }
        viYUVChangeBufferM(mmioBase, viInst,
                          genBuf[viNum].Y,
                          genBuf[viNum].U,
                          genBuf[viNum].V);
        firstField = 1;
    }

    viAckCAP_ACKM(mmioBase);    /* read comments above on the acknowledge */
}

void
viTestISR(void)
{
#pragma TCS_handler

    AppModel_suspend_scheduling();
    AppModel_run_on_sstack((AppModel_Fun)_viTestISR, Null);
    AppModel_resume_scheduling();
}


void
mmBufUpdate()
{
    Int         mmtmpNum;

    mmtmpNum = (mmNum + 1) % NUM_BUF_ENTRIES;
    if (genBuf[mmtmpNum].flag == VID_RDY_MM) {
        genBuf[mmNum].flag = VID_RDY_VO;
        mmNum = mmtmpNum;
    }
}

static void
SetupICP()
{
    tmLibdevErr_t err;
 
    if (err = icpOpen(&icpInst))
        my_abort("icpOpen", err);
    memset((char *) &icpInstSup, 0, sizeof (icpInstanceSetup_t));
    icpInstSup.interruptPriority = intPRIO_4;
    icpInstSup.isr = NULL;
    if (err = icpInstanceSetup(icpInst, &icpInstSup))
        my_abort("icpInstanceSetup", err);

    if (err = icpLoadCoeff(icpInst, NULL))
       my_abort("icpLoadCoeff", err);

    memset((char *) &icpImage, 0, sizeof (icpImageColorConversion_t));
    icpImage.yInputStride = cifStride;
    icpImage.uvInputStride = (cifStride >> 1);
    icpImage.inputHeight = cifHeight;
    icpImage.inputWidth = cifWidth;
    icpImage.outputStride = cifWidth<<1;
    icpImage.outputHeight = cifHeight;
    icpImage.outputWidth = cifWidth;
    icpImage.filterBypass = icpFILTER;
    icpImage.outputPixelOffset = 0;
    icpImage.inType = vtfYUV;
    icpImage.inu.inYUVFormat = vdfYUV422Planar;
    icpImage.outputDestination = icpSDRAM;
#ifdef __LITTLE_ENDIAN__
    icpImage.littleEndian = True;
#else
    icpImage.littleEndian = False;
#endif
    icpImage.outType = vtfYUV;
    icpImage.outu.outYUVFormat = vdfYUV422Sequence;
}

void
CIF422OVERLAY(UInt32 yP, UInt32 uP, UInt32 vP,
          UInt32 ovP)
{
    UInt8 *pp;
    UInt8 *pY0;
    UInt8 *pY1;
    UInt8 *pU;
    UInt8 *pV;
    UInt  *tmpPtr;
    Int    i, j;

    pY0 = (UInt8 *) yP;
    pU = (UInt8 *) uP;
    pV = (UInt8 *) vP;
    pp = (UInt8 *) yP;
    pY1 = ++pp;

    tmpPtr = (UInt *) ovP;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -