📄 main.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <tm1/mmio.h>
#include <tm1/tmPCSW.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmICP.h>
#include <tm1/tmVI.h>
#include <tm1/tmAvFormats.h>
#include <tmlib/dprintf.h>
#include <tmlib/tmlibc.h>
#include <tmlib/AppModel.h>
#include <tm1/tmHelp.h>
#define GLOBAL
#include "global_e.h"
#include "sim.h"
FILE *streamfile;
#define VI_READY 2
#define VI_NOT_READY 4
#define NUM_VI_BUF 2
static Int LOOPCOUNT = 25;
typedef struct _videoBuf { /* video buffer structure example */
Pointer Y; /* buffer pointer for Y */
Pointer U; /* buffer pointer for U */
Pointer V; /* buffer pointer for V */
UInt32 flag; /* flags used in buffer management */
} vBuf, *pvBuf;
static unsigned char *yTemp[NUM_VI_BUF];
static unsigned char *uTemp[NUM_VI_BUF];
static unsigned char *vTemp[NUM_VI_BUF];
static unsigned char *midTemp;
static volatile int interrupt_done;
static vBuf viBuf[NUM_VI_BUF];
static Int bufNum = 0;
static Int tmpNum = 0;
static Int displayNum = 0;
static Int viInst = -1;
static Int icpInst = -1;
static icpInstanceSetup_t icpInstSup;
static icpImageColorConversion_t icpImage;
static icpImageHorzVert_t hvImage;
static viInstanceSetup_t viInstSup;
static viYUVSetup_t viYUVInstSup;
static tmLibdevErr_t err;
static volatile int got1SField = 0;
static Int not555a = 0;
static int vidStride = 384;
static Int vidWidth = 352;
static Int vidHeight = 240;
static Int yScanWidth = 384; /* half resolution */
static Int uvScanWidth = 192;
static Int yScanHeight = 288;
static Int uvScanHeight = 288;
static UInt8 *DPhyAdr = (UInt8 *) 0xfe000000;
static Int Dstride = 2048;
static Int Dbpp = 2;
static tmVideoAnalogStandard_t videoStandard = vasNone;
static tmVideoAnalogAdapter_t adapterType = vaaCVBS;
static Int szY, szUV;
static void my_abort(Char * name, Int err);
static Char *Header = "\nTriMedia Video-In Example Program Version 2.0\n\n";
static void icpDisplay()
{
icpImage.yBase = yTemp[bufNum];
icpImage.uBase = uTemp[bufNum];
icpImage.vBase = vTemp[bufNum];
interrupt_done = 0;
if (err = icpColorConversion(icpInst, &icpImage))
my_abort("icpColorConversion", err);
while (icpCheckBUSY());
viBuf[bufNum].flag = VI_READY;
}
static void icp_handler(void)
{
#pragma TCS_handler
#pragma TCS_atomic
interrupt_done = 1;
icpEnableACK_DONE();
}
void Icp_my()
{
int destHeight;
int destWidth;
destHeight = vidHeight/2;
destWidth = vidWidth/2;
hvImage.filterBypass = icpBYPASS;
hvImage.outputPixelOffset = 0.0;
hvImage.inputStride = vidStride;
hvImage.inputWidth = vidWidth;
hvImage.inputHeight = vidHeight;
hvImage.outputStride = vidStride;
hvImage.outputWidth = vidWidth;
hvImage.outputHeight = destHeight;
hvImage.imageBase = viBuf[bufNum].Y;
hvImage.outputImage = midTemp;
interrupt_done = 0;
if (err = icpVertFilter(icpInst, &hvImage))
{
printf("Error in icpVertFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
hvImage.inputHeight = destHeight;
hvImage.outputStride = vidStride/2;
hvImage.outputWidth = destWidth;
hvImage.imageBase = midTemp;
hvImage.outputImage = yTemp[bufNum];
while (icpCheckBUSY());
interrupt_done = 0;
if (err = icpHorzFilter(icpInst, &hvImage))
{
printf("Error in icpHorzFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
hvImage.inputStride = vidStride/2;
hvImage.inputWidth = vidWidth/2;
hvImage.inputHeight = vidHeight;
hvImage.outputStride = vidStride/2;
hvImage.outputWidth = vidWidth/2;
hvImage.outputHeight = destHeight;
hvImage.imageBase = viBuf[bufNum].U;
hvImage.outputImage = midTemp;
while (icpCheckBUSY());
interrupt_done = 0;
if (err = icpVertFilter(icpInst, &hvImage))
{
printf("Error in icpVertFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
hvImage.inputHeight = destHeight;
hvImage.outputStride = vidStride/4;
hvImage.outputWidth = destWidth/2;
hvImage.imageBase = midTemp;
hvImage.outputImage = uTemp[bufNum];
while (icpCheckBUSY());
interrupt_done = 0;
if (err = icpHorzFilter(icpInst, &hvImage))
{
printf("Error in icpHorzFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
hvImage.inputStride = vidStride/2;
hvImage.inputWidth = vidWidth/2;
hvImage.inputHeight = vidHeight;
hvImage.outputStride = vidStride/2;
hvImage.outputWidth = vidWidth/2;
hvImage.outputHeight = destHeight;
hvImage.imageBase = viBuf[bufNum].V;
hvImage.outputImage = midTemp;
while (icpCheckBUSY());
interrupt_done = 0;
if (err = icpVertFilter(icpInst, &hvImage))
{
printf("Error in icpVertFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
hvImage.inputHeight = destHeight;
hvImage.outputStride = vidStride/4;
hvImage.outputWidth = destWidth/2;
hvImage.imageBase = midTemp;
hvImage.outputImage = vTemp[bufNum];
while (icpCheckBUSY());
interrupt_done = 0;
if (err = icpHorzFilter(icpInst, &hvImage))
{
printf("Error in icpHorzFilter: %x \n", err);
exit(0);
}
while (icpCheckBUSY());
return;
}
static void SetupICP()
{
if (err = icpOpen(&icpInst))
my_abort("icpOpen", err);
memset((Char *) &icpInstSup, 0, sizeof (icpInstanceSetup_t));
icpInstSup.interruptPriority = intPRIO_3;
icpInstSup.isr = icp_handler;
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 = yScanWidth/2;
icpImage.uvInputStride = uvScanWidth/2;
icpImage.inputHeight = vidHeight/2;
icpImage.inputWidth = vidWidth/2;
icpImage.outputHeight = vidHeight/2;
icpImage.outputWidth = vidWidth/2;
icpImage.outputImage = DPhyAdr;
icpImage.outputStride = Dstride;
icpImage.filterBypass = icpBYPASS;
icpImage.outputPixelOffset = 0.0;
icpImage.inFormat = vdfYUV422Planar;
icpImage.outputDestination = icpPCI;
#ifdef __LITTLE_ENDIAN__
icpImage.littleEndian = True;
#else
#if defined(__BIG_ENDIAN__) && defined(__TCS_WinNT__)
icpImage.littleEndian = True;
#else
icpImage.littleEndian = False;
#endif
#endif
if (Dbpp == 1)
icpImage.outFormat = vdfRGB8A_233;
else if (Dbpp == 2 && not555a)
icpImage.outFormat = vdfRGB16;
else if (Dbpp == 2 && (!not555a))
icpImage.outFormat = vdfRGB15Alpha;
else if (Dbpp == 3)
icpImage.outFormat = vdfRGB24;
else if (Dbpp == 4)
icpImage.outFormat = vdfRGB24Alpha;
}
static void _viMyISR()
{
UInt32 vi_status;
vi_status = MMIO(VI_STATUS);
if ((vi_status & 0x1) == 0)
{
return;
}
if (viHBE(vi_status))
{
viAckHBE_ACK();
return;
}
if (viODD(vi_status))
{
viAckCAP_ACK();
}
else {
tmpNum = bufNum ? 0 : 1;
if (viBuf[tmpNum].flag == VI_READY)
{
viBuf[bufNum].flag = VI_NOT_READY;
displayNum = bufNum;
bufNum = tmpNum;
viYUVChangeBuffer(viInst, viBuf[bufNum].Y, viBuf[bufNum].U, viBuf[bufNum].V);
got1SField = 1;
}
viAckCAP_ACK();
}
}
static void viMyISR()
{
#pragma TCS_handler
AppModel_suspend_scheduling();
AppModel_run_on_sstack((AppModel_Fun)_viMyISR, Null);
AppModel_resume_scheduling();
}
static void SetupVI()
{
tmLibdevErr_t err;
UInt startX, startY, endX, endY;
if (err = viOpen(&viInst))
my_abort("viOpen", err);
fprintf(stderr, "If input device is not proper connected, the viGetVideoStandard routine will take a while.\n");
if (videoStandard == vasNone)
{
/* Get the video standard from specified adapter */
if ((err = viGetAdapterVideoStandard(viInst, adapterType, 0, &videoStandard))
|| videoStandard == vasNone)
{
fprintf(stderr, "\nCould not determine the input standard\n");
exit(0);
}
else if (videoStandard == vasNTSC)
{
fprintf(stderr, "\nI think I am getting NTSC input\n");
}
else if (videoStandard == vasPAL)
{
fprintf(stderr, "\nI think I am getting PAL input\n");
}
else if (videoStandard == vasSECAM)
{
fprintf(stderr, "\nI think I am getting SECAM input\n");
}
else
{
fprintf(stderr,"\nSorry ,I don't know what standard\n");
}
}
memset((Char *) &viInstSup, 0, sizeof (viInstanceSetup_t));
viInstSup.interruptPriority = intPRIO_4;
viInstSup.isr = viMyISR;
viInstSup.videoStandard = videoStandard;
viInstSup.adapterType = adapterType;
if (err = viInstanceSetup(viInst, &viInstSup))
my_abort("viInstanceSetup", err);
memset((Char *) &viYUVInstSup, 0, sizeof (viYUVSetup_t));
viYUVInstSup.thresholdReachedEnable = False;
viYUVInstSup.captureCompleteEnable = True;
viYUVInstSup.cositedSampling = True;
viYUVInstSup.mode = viHALFRES;
/* Try to get horizontal and vertical start position from vi */
if (viGetDefaultAcquisitionWnd(viInst, &startX, &startY, &endX, &endY) == TMLIBDEV_OK)
{
if (viYUVInstSup.mode == viHALFRES)
/* Make sure startX is a multiple of 4 */
viYUVInstSup.startX = (startX + 3) & 0xFC;
else
viYUVInstSup.startX = startX;
viYUVInstSup.startY = startY;
}
else
{
/* If not available by vi, use defaults */
viYUVInstSup.startX = 4;
viYUVInstSup.startY = 11;
}
viYUVInstSup.width = vidWidth;
viYUVInstSup.height = vidHeight;
viYUVInstSup.yBase = viBuf[0].Y;
viYUVInstSup.uBase = viBuf[0].U;
viYUVInstSup.vBase = viBuf[0].V;
viYUVInstSup.yDelta = 33; /* (384 - 352) + 1 */
viYUVInstSup.uDelta = 17; /* (192 - 176) + 1 */
viYUVInstSup.vDelta = 17;
if (err = viYUVSetup(viInst, &viYUVInstSup))
my_abort("viYUVSetup", err);
}
static void viUsage()
{
printf("usage: ld vitest.out [-d f9000000] "
"[-s 2400] [-b 3] [-not555a] [-l 1000] [pal|ntsc] [cvbs|s-video]\n");
}
static void viCheckArgcv(Int argc, Char **argv)
{
Int mark = 1;
if (argc == 1)
viUsage();
argc--;
while (argc > 0)
{
if (strcmp(argv[mark], "-d") == 0)
{
argc--;
mark++;
sscanf(argv[mark], "%x", &DPhyAdr);
argc--;
mark++;
}
else if (strcmp(argv[mark], "-s") == 0)
{
argc--;
mark++;
sscanf(argv[mark], "%d", &Dstride);
argc--;
mark++;
}
else if (strcmp(argv[mark], "-b") == 0)
{
argc--;
mark++;
sscanf(argv[mark], "%d", &Dbpp);
argc--;
mark++;
}
else if (strcmp(argv[mark], "-l") == 0)
{
argc--;
mark++;
argc--;
mark++;
}
else if (strcmp(argv[mark], "-not555a") == 0)
{
argc--;
mark++;
not555a = 1;
}
else if (strcmp(argv[mark], "ntsc") == 0)
{ /* NTSC */
videoStandard = vasNTSC;
argc--;
mark++;
}
else if (strcmp(argv[mark], "pal") == 0)
{ /* PAL */
videoStandard = vasPAL;
argc--;
mark++;
}
else if (strcmp(argv[mark], "cvbs") == 0)
{ /* CVBS */
adapterType = vaaCVBS;
argc--;
mark++;
}
else if (strcmp(argv[mark], "s-video") == 0)
{ /* S-Video */
adapterType = vaaSvideo;
argc--;
mark++;
}
else
{
viUsage();
argc--;
mark++;
}
}
#ifndef __TCS_nohost__
if (((Int *) DPhyAdr)[0] == 0)
{
fprintf(stderr, "I could be wrong but is %x indeed\n"
"the address of your video buffer?\n"
"I am going to write into it directly.....\n"
"You can verify the address in\n"
"\tControl Panel\\System\\device Manager"
"\\Display Adapter\\<whatever>\\Resources\n"
"Press any key to continue, ^C to quit\n", DPhyAdr);
getchar();
}
#endif
}
static void my_abort(Char * name, Int err)
{
assert(name != Null);
fprintf(stderr, "%s failed, error code %x\n", name, err);
exit(-1);
}
static void AllocBuffers()
{
Int szY, szUV, i;
pprocCapabilities_t cap;
szY = yScanWidth * (yScanHeight + 4);
szUV = uvScanWidth * (uvScanHeight + 4);
if (err = procGetCapabilities(&cap))
my_abort("procGetCapabilities", err);
if (cap->revisionID <= PROC_REVISION_1_0S && cap->deviceID <= PROC_DEVICE_TM1000)
{
fprintf(stderr, "Detected tm1s1.0 or older version of chip. "
"They are no longer supported.\n"
"Please contact Philips TriMedia to exchange to "
"a newer version of chip.\n");
exit(-1);
}
for (i = 0; i < NUM_VI_BUF; i++)
{
viBuf[i].Y = _cache_malloc(szY, -1);
viBuf[i].U = _cache_malloc(szUV, -1);
viBuf[i].V = _cache_malloc(szUV, -1);
viBuf[i].flag = VI_READY;
memset(viBuf[i].Y, 0, szY);
memset(viBuf[i].U, 0, szUV);
memset(viBuf[i].V, 0, szUV);
_cache_copyback((Char *) viBuf[i].Y, szY);
_cache_copyback((Char *) viBuf[i].U, szUV);
_cache_copyback((Char *) viBuf[i].V, szUV);
/********************************************************************/
yTemp[i] = (unsigned char *)_cache_malloc(szY, -1);
uTemp[i] = (unsigned char *)_cache_malloc(szUV, -1);
vTemp[i] = (unsigned char *)_cache_malloc(szUV, -1);
memset(yTemp[i], 0, szY);
memset(uTemp[i], 0, szUV);
memset(vTemp[i], 0, szUV);
_cache_copyback((Char *) yTemp[i], szY);
_cache_copyback((Char *) uTemp[i], szUV);
_cache_copyback((Char *) vTemp[i], szUV);
}
midTemp = (unsigned char *)_cache_malloc(szY, -1);
memset(midTemp, 0, szY);
_cache_copyback((Char *) midTemp, szY);
}
FreeBuffer()
{
int i;
for(i = 0; i < NUM_VI_BUF; i++)
{
_cache_free((Pointer) yTemp[i]);
_cache_free((Pointer) uTemp[i]);
_cache_free((Pointer) vTemp[i]);
_cache_free((Pointer) viBuf[i].Y);
_cache_free((Pointer) viBuf[i].U);
_cache_free((Pointer) viBuf[i].V);
}
_cache_free((Pointer) midTemp);
}
PictImage *ReadImage()
{
int i;
unsigned char *buf;
PictImage *Pict;
Icp_my();
Pict = InitImage(pels*lines);
buf = yTemp[bufNum];
for( i=0; i<lines; i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -