diff options
| author | 2015-11-08 12:56:12 +0100 | |
|---|---|---|
| committer | 2015-11-08 12:56:12 +0100 | |
| commit | 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch) | |
| tree | f310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/lib/util/vbiparse.c | |
| parent | a57b46ae933badd7441ce1644711dbb851e2b504 (diff) | |
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/lib/util/vbiparse.c')
| -rw-r--r-- | src/lib/util/vbiparse.c | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/src/lib/util/vbiparse.c b/src/lib/util/vbiparse.c deleted file mode 100644 index 9c6c39fc4ea..00000000000 --- a/src/lib/util/vbiparse.c +++ /dev/null @@ -1,408 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - vbiparse.c - - Parse Philips codes and other data from VBI lines. - -***************************************************************************/ - -#include "osdcore.h" -#include "vbiparse.h" -#include <math.h> - - - -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define PRINTF_WHITE_FLAG 0 - - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -#define MAX_SOURCE_WIDTH 1024 -#define MAX_CLOCK_DIFF 3 - - - -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ - -/*------------------------------------------------- - vbi_parse_manchester_code - parse a Manchester - code from a line of video data --------------------------------------------------*/ - -int vbi_parse_manchester_code(const UINT16 *source, int sourcewidth, int sourceshift, int expectedbits, UINT32 *result) -{ - UINT8 srcabs[MAX_SOURCE_WIDTH]; - UINT8 min, max, mid, srcabsval; - double clock, bestclock; - int x, firstedge; - int besterr; - - /* fail if the width is too large */ - if (sourcewidth > MAX_SOURCE_WIDTH) - return 0; - - /* find highs and lows in the line */ - min = 0xff; - max = 0x00; - for (x = 0; x < sourcewidth; x++) - { - UINT8 rawsrc = source[x] >> sourceshift; - min = MIN(min, rawsrc); - max = MAX(max, rawsrc); - } - - /* bail if the line is all black or all white */ - if (max < 0x80 || min > 0x80) - return 0; - - /* determine the midpoint and then set the thresholds to be halfway */ - mid = (min + max) / 2; - min = mid - (mid - min) / 2; - max = mid + (max - mid) / 2; - - /* convert the source into absolute high/low */ - srcabsval = (source[0] > mid); - for (x = 0; x < sourcewidth; x++) - { - UINT8 rawsrc = source[x] >> sourceshift; - if (rawsrc >= max) - srcabsval = 1; - else if (rawsrc <= min) - srcabsval = 0; - srcabs[x] = srcabsval; - } - - /* find the first transition; this is assumed to be the middle of the first bit */ - for (x = 0; x < sourcewidth - 1; x++) - if (srcabs[x] != srcabs[x + 1]) - break; - if (x == sourcewidth - 1) - return 0; - firstedge = x; - - /* now scan to find a clock that has a nearby transition on each beat */ - bestclock = 0; - besterr = 1000; - for (clock = (double)sourcewidth / (double)expectedbits; clock >= 2.0; clock -= 1.0 / (double)expectedbits) - { - int error = 0; - - /* scan for all the expected bits */ - for (x = 1; x < expectedbits; x++) - { - int curbit = firstedge + (double)x * clock; - int offby; - - /* look for a match that is off by an amount up to the maximum */ - for (offby = 0; offby <= MAX_CLOCK_DIFF; offby++) - if (srcabs[curbit + offby + 0] != srcabs[curbit + offby + 1] || srcabs[curbit - offby + 0] != srcabs[curbit - offby + 1]) - break; - - /* if we never found the edge, fail immediately */ - if (offby > MAX_CLOCK_DIFF) - break; - - /* only continue if we're still in the running */ - error += offby; - if (error >= besterr) - break; - } - - /* if we got to the end, this is the best candidate so far */ - if (x == expectedbits) - { - besterr = error; - bestclock = clock; - } - } - - /* if nobody matched, fail */ - if (bestclock == 0) - return 0; - - /* now extract the bits */ - for (x = 0; x < expectedbits; x++) - { - int leftstart = firstedge + ceil(((double)x - 0.5) * bestclock); -// int leftmid = firstedge + ((double)x - 0.25) * bestclock; - int leftend = firstedge + floor(((double)x - 0.0) * bestclock); - int rightstart = firstedge + ceil(((double)x + 0.0) * bestclock); -// int rightmid = firstedge + ((double)x + 0.25) * bestclock; - int rightend = firstedge + floor(((double)x + 0.5) * bestclock); - int leftavg, rightavg, leftabs, rightabs; - int confidence = 0; - int tx; - - /* compute left and right average values */ - leftavg = 0; - for (tx = leftstart; tx <= leftend; tx++) - leftavg += (UINT8)(source[tx] >> sourceshift) - mid; - leftabs = (leftavg >= 0); - leftavg = (leftavg < 0) ? -leftavg : leftavg; - - rightavg = 0; - for (tx = rightstart; tx <= rightend; tx++) - rightavg += (UINT8)(source[tx] >> sourceshift) - mid; - rightabs = (rightavg >= 0); - rightavg = (rightavg < 0) ? -rightavg : rightavg; - - /* all bits should be marked by transitions; fail if we don't get one */ - if (leftabs == rightabs) - return 0; - - /* store the bit and its confidence level */ - confidence = leftavg + rightavg; - result[x] = (leftabs < rightabs) | (confidence << 1); - } - return expectedbits; -} - - -/*------------------------------------------------- - vbi_parse_white_flag - compute the "white - flag" from a line of video data --------------------------------------------------*/ - -int vbi_parse_white_flag(const UINT16 *source, int sourcewidth, int sourceshift) -{ - int histo[256] = { 0 }; - int minval = 0xff; - int maxval = 0x00; - int subtract; - int peakval; - int result; - int x; - - /* compute a histogram of values */ - for (x = 0; x < sourcewidth; x++) - { - UINT8 yval = source[x] >> sourceshift; - histo[yval]++; - } - - /* remove the lowest 1% of the values to account for noise and determine the minimum */ - subtract = sourcewidth / 100; - for (minval = 0; minval < 255; minval++) - if ((subtract -= histo[minval]) < 0) - break; - - /* remove the highest 1% of the values to account for noise and determine the maximum */ - subtract = sourcewidth / 100; - for (maxval = 255; maxval > 0; maxval--) - if ((subtract -= histo[maxval]) < 0) - break; - - /* this is useful for debugging issues with white flag detection */ - if (PRINTF_WHITE_FLAG) - { - printf("Histo: min=%02X max=%02X\n", minval, maxval); - for (x = 0; x < 256; x++) - if (histo[x] != 0) printf("%dx%02X\n", histo[x], x); - } - - /* ignore if we have no dynamic range */ - if (maxval - minval < 10) - { - if (PRINTF_WHITE_FLAG) - printf("White flag NOT detected; threshold too low\n"); - return FALSE; - } - - /* - At this point, there are two approaches that have been tried: - - 1. Find the peak value and call it white if the peak is above - the 90% line - - 2. Ignore the first and last 20% of the line and count how - many pixels are above some threshold (75% line was used). - Call it white if at least 80% of the pixels are above - the threshold. - - Both approaches agree 99% of the time, but the first tends to - be more correct when there is a discrepancy. - */ - - /* determine where the peak is */ - peakval = 0; - for (x = 1; x < 256; x++) - if (histo[x] > histo[peakval]) - peakval = x; - - /* return TRUE if it is above the 90% mark */ - result = (peakval > minval + 9 * (maxval - minval) / 10); - if (PRINTF_WHITE_FLAG) - printf("White flag %s: peak=%02X thresh=%02X\n", result ? "detected" : "NOT detected", peakval, minval + 9 * (maxval - minval) / 10); - return result; - -#ifdef UNUSED_CODE -{ - int above = 0; - int thresh; - - /* alternate approach: */ - - /* ignore the first 1/5 and last 1/5 of the line for the remaining computations */ - source += sourcewidth / 5; - sourcewidth -= 2 * (sourcewidth / 5); - - /* count how many values were above the 75% mark of the range */ - thresh = minval + 3 * (maxval - minval) / 4; - for (x = 0; x < sourcewidth; x++) - { - UINT8 yval = source[x] >> sourceshift; - above += (yval >= thresh); - } - /* if at least 80% of the pixels are above the threshold, we'll call it white */ - return ((above * 100) / sourcewidth >= 80); -} -#endif -} - - -/*------------------------------------------------- - vbi_parse_all - parse everything from a video - frame --------------------------------------------------*/ - -/** - * @fn void vbi_parse_all(const UINT16 *source, int sourcerowpixels, int sourcewidth, int sourceshift, vbi_metadata *vbi) - * - * @brief Vbi parse all. - * - * @param source Source for the. - * @param sourcerowpixels The sourcerowpixels. - * @param sourcewidth The sourcewidth. - * @param sourceshift The sourceshift. - * @param [in,out] vbi If non-null, the vbi. - */ - -void vbi_parse_all(const UINT16 *source, int sourcerowpixels, int sourcewidth, int sourceshift, vbi_metadata *vbi) -{ - UINT32 bits[2][24]; - UINT8 bitnum; - - /* first reset it all */ - memset(vbi, 0, sizeof(*vbi)); - - /* get the white flag */ - vbi->white = vbi_parse_white_flag(source + 11 * sourcerowpixels, sourcewidth, sourceshift); - - /* parse line 16 */ - if (vbi_parse_manchester_code(source + 16 * sourcerowpixels, sourcewidth, sourceshift, 24, bits[0]) == 24) - for (bitnum = 0; bitnum < 24; bitnum++) - vbi->line16 = (vbi->line16 << 1) | (bits[0][bitnum] & 1); - - /* parse line 17 */ - if (vbi_parse_manchester_code(source + 17 * sourcerowpixels, sourcewidth, sourceshift, 24, bits[0]) == 24) - for (bitnum = 0; bitnum < 24; bitnum++) - vbi->line17 = (vbi->line17 << 1) | (bits[0][bitnum] & 1); - - /* parse line 18 */ - if (vbi_parse_manchester_code(source + 18 * sourcerowpixels, sourcewidth, sourceshift, 24, bits[1]) == 24) - for (bitnum = 0; bitnum < 24; bitnum++) - vbi->line18 = (vbi->line18 << 1) | (bits[1][bitnum] & 1); - - /* pick the best out of lines 17/18 */ - /* if we only got one or the other, that's all we have */ - if (vbi->line17 == 0) - vbi->line1718 = vbi->line18; - else if (vbi->line18 == 0) - vbi->line1718 = vbi->line17; - - /* if they agree, we're golden */ - else if (vbi->line17 == vbi->line18) - vbi->line1718 = vbi->line17; - - /* if they don't agree, we have to pick one */ - else - { - /* if both are frame numbers, and one is not valid BCD, pick the other */ - if ((vbi->line17 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE && (vbi->line18 & VBI_MASK_CAV_PICTURE) == VBI_CODE_CAV_PICTURE) - { - if ((vbi->line17 & 0xf000) > 0x9000 || (vbi->line17 & 0xf00) > 0x900 || (vbi->line17 & 0xf0) > 0x90 || (vbi->line17 & 0xf) > 0x9) - vbi->line1718 = vbi->line18; - else if ((vbi->line18 & 0xf000) > 0x9000 || (vbi->line18 & 0xf00) > 0x900 || (vbi->line18 & 0xf0) > 0x90 || (vbi->line18 & 0xf) > 0x9) - vbi->line1718 = vbi->line17; - } - - /* if still nothing, then scan through the bits and pick the ones with the most confidence */ - if (vbi->line1718 == 0) - for (bitnum = 0; bitnum < 24; bitnum++) - vbi->line1718 = (vbi->line1718 << 1) | ((bits[0][bitnum] > bits[1][bitnum]) ? (bits[0][bitnum] & 1) : (bits[1][bitnum] & 1)); - } -} - - -/*------------------------------------------------- - vbi_metadata_pack - pack the VBI data down - into a smaller form for storage --------------------------------------------------*/ - -/** - * @fn void vbi_metadata_pack(UINT8 *dest, UINT32 framenum, const vbi_metadata *vbi) - * - * @brief Vbi metadata pack. - * - * @param [in,out] dest If non-null, destination for the. - * @param framenum The framenum. - * @param vbi The vbi. - */ - -void vbi_metadata_pack(UINT8 *dest, UINT32 framenum, const vbi_metadata *vbi) -{ - dest[0] = framenum >> 16; - dest[1] = framenum >> 8; - dest[2] = framenum >> 0; - dest[3] = vbi->white; - dest[4] = vbi->line16 >> 16; - dest[5] = vbi->line16 >> 8; - dest[6] = vbi->line16 >> 0; - dest[7] = vbi->line17 >> 16; - dest[8] = vbi->line17 >> 8; - dest[9] = vbi->line17 >> 0; - dest[10] = vbi->line18 >> 16; - dest[11] = vbi->line18 >> 8; - dest[12] = vbi->line18 >> 0; - dest[13] = vbi->line1718 >> 16; - dest[14] = vbi->line1718 >> 8; - dest[15] = vbi->line1718 >> 0; -} - - -/*------------------------------------------------- - vbi_metadata_unpack - unpack the VBI data - from a smaller form into the full structure --------------------------------------------------*/ - -/** - * @fn void vbi_metadata_unpack(vbi_metadata *vbi, UINT32 *framenum, const UINT8 *source) - * - * @brief Vbi metadata unpack. - * - * @param [in,out] vbi If non-null, the vbi. - * @param [in,out] framenum If non-null, the framenum. - * @param source Source for the. - */ - -void vbi_metadata_unpack(vbi_metadata *vbi, UINT32 *framenum, const UINT8 *source) -{ - if (framenum != NULL) - *framenum = (source[0] << 16) | (source[1] << 8) | source[2]; - vbi->white = source[3]; - vbi->line16 = (source[4] << 16) | (source[5] << 8) | source[6]; - vbi->line17 = (source[7] << 16) | (source[8] << 8) | source[9]; - vbi->line18 = (source[10] << 16) | (source[11] << 8) | source[12]; - vbi->line1718 = (source[13] << 16) | (source[14] << 8) | source[15]; -} |
