summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/vbiparse.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
commit7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch)
treef310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/lib/util/vbiparse.c
parenta57b46ae933badd7441ce1644711dbb851e2b504 (diff)
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/lib/util/vbiparse.c')
-rw-r--r--src/lib/util/vbiparse.c408
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];
-}