📄 tbc.c
字号:
/*
* Copyright (c) 1997,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 : voTbc.c 2.2
*
* Last update : 3/24/2000
*
* Description :
*
* See attached README
*
* Revision :
* Built for TCS2.2 release
*
*/
#ifdef __TCS_Win95__
/* #include "tmman.h" */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <tm1/mmio.h>
#include <ops/custom_defs.h>
#include <tm1/tmVI.h>
#include <tm1/tmVO.h>
#include <tmlib/dprintf.h>
#include "tbc.h"
#define FRAME_HEIGHT_NTSC 525
#define FRAME_WIDTH_NTSC 858 /* 525 lines x 858 pixels for PAL, databook, Table 7-9 */
#define FRAME_FREQ_NTSC 60
#define FRAME_HEIGHT_PAL 625
#define FRAME_WIDTH_PAL 864 /* 625 lines x 864 pixels for PAL, databook, Table 7-9 */
#define FRAME_FREQ_PAL 50
static int frame_widths[2] = { 858, 864 } ;
static int frame_heights[2] = { 525, 625 } ;
unsigned compute_freq(float, float, unsigned);
void tbcInit(int mode, float gain, float min, float max)
{
unsigned err;
err = procGetCapabilities(&voTbc.procCap);
if (err) {
fprintf(stderr, "Could not get procCaps\n");
exit(1);
}
if (gain==0.0) gain = 0.01;
if (min==0) min = 0.9999;
if (max==0) max = 1.0001;
voTbc.clockref = MMIO(VO_CLOCK);
voTbc.clockmin = min * voTbc.clockref;
voTbc.clockmax = max * voTbc.clockref;
voTbc.frame_width = frame_widths[mode==vasPAL];
voTbc.frame_height = frame_heights[mode==vasPAL];
voTbc.gain = gain;
voTbc.frame = 0;
tbcSetPhase(0);
}
void
tbcSetPhase(float phase)
{
voTbc.skew = fmod(phase, 360.0);
}
float
tbcGetPhase(void)
{
unsigned vo_status, vi_status;
int frame_height, frame_width;
int iphbit, ophbit;
float phase;
frame_width = voTbc.frame_width;
frame_height = voTbc.frame_height;
vi_status = MMIO(VI_STATUS);
/* (x, y) scan position, databook, Figure 7-26, Video Out MMIO registers */
/* VI_STATUS : bits[31..20] = current input y pos'n. [19..8] = current x */
vo_status = MMIO(VO_STATUS);
/* (x, y) scan position, databook, Figure 7-26, Video Out MMIO registers */
/* VO_STATUS : bits[31..20] = current output y pos'n. [19..8] = current x */
iphbit = (vi_status>>20) * frame_height + ((vi_status>>8)&0xFFF);
/* video in phase position (bits) */
ophbit = (vo_status>>20) * frame_height + ((vo_status>>8)&0xFFF);
/* video out phase position (bits) */
phase = (ophbit - iphbit) / (float) ( frame_height * frame_width);
/* video out phase w.r.t. video in, range -1 - +1 */
return phase * 360;
}
void
tbcAdjust(void)
{
unsigned clock;
float diff;
if (!(MMIO(VI_STATUS)&0x10))
return;
voTbc.phase = tbcGetPhase();
diff = (voTbc.skew - voTbc.phase) * (1./360.) ;
clock = compute_freq(diff, voTbc.gain, voTbc.clockref);
if (clock < voTbc.clockmin)
clock = voTbc.clockmin;
else if (clock > voTbc.clockmax)
clock = voTbc.clockmax;
MMIO(VO_CLOCK) = clock;
voTbc.frame ++;
}
/*
* clock = (diff * gain + 1) * clock
* REF
*/
#define FRACUMUL(a, b, sh) ((UMULM(a, b) << sh) + (((a) * (b)) >> (32-sh)))
#define FRACMUL(a, b, sh) ((IMULM(a, b) << sh) + (((a) * (b)) >> (32-sh)))
#define TOFRAC(f) (int)((ff_base * f))
unsigned static
compute_freq(float phase_diff, float fgain, unsigned clockref)
{
float ff_base = 0x40000000;
unsigned ff_3, diff, gain;
diff = TOFRAC(phase_diff);
gain = TOFRAC(fgain);
diff = FRACMUL(diff, gain, 2) + 0x40000000;
ff_3 = FRACUMUL(clockref, diff, 2);
return ff_3;
}
/*
* convert VO_CLOCK to clock frequency in Hz
* see Figure 7-6 of databook
*/
unsigned
tbcClockFreq(unsigned clock)
{
if (clock&0x80000000)
return UMULM(voTbc.procCap->cpuClockFrequency*9, clock&~0x80000000);
else
return UMULM(voTbc.procCap->cpuClockFrequency*3, clock);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -