summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-08-07 15:07:12 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-08-07 15:07:12 +0000
commit3107dc2dffe23f7e52b4f46d35d8e458c6b663b4 (patch)
tree505b934c0f788d308e7aef276610c3ca73aa1436 /src/lib
parent1c6a1e7df7622d7782035a230e6661ec6c7fff19 (diff)
ldverify now prints transient progress to stderr, allows for frame #0,
and reports if no white flags were seen. Fixed bug in aviio.c which could cause an infinite loop if attempting to read sound beyond the end of the file. Rewrote the white flag detection to use a histogram for outlier detection and peak identification.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/util/aviio.c7
-rw-r--r--src/lib/util/vbiparse.c103
2 files changed, 99 insertions, 11 deletions
diff --git a/src/lib/util/aviio.c b/src/lib/util/aviio.c
index 8598f868ba4..d664c8214ab 100644
--- a/src/lib/util/aviio.c
+++ b/src/lib/util/aviio.c
@@ -863,6 +863,13 @@ avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample
chunkbase = chunkend;
}
+ /* if we hit the end, fill the rest with silence */
+ if (chunknum == stream->chunks)
+ {
+ memset(output, 0, numsamples * 2);
+ break;
+ }
+
/* expand the tempbuffer to hold the data if necessary */
avierr = expand_tempbuffer(file, stream->chunk[chunknum].length);
if (avierr != AVIERR_NONE)
diff --git a/src/lib/util/vbiparse.c b/src/lib/util/vbiparse.c
index ba9f29e10cd..dd520ab67a7 100644
--- a/src/lib/util/vbiparse.c
+++ b/src/lib/util/vbiparse.c
@@ -16,6 +16,14 @@
/***************************************************************************
+ DEBUGGING
+***************************************************************************/
+
+#define PRINTF_WHITE_FLAG 0
+
+
+
+/***************************************************************************
CONSTANTS
***************************************************************************/
@@ -169,25 +177,98 @@ int vbi_parse_manchester_code(const UINT16 *source, int sourcewidth, int sources
int vbi_parse_white_flag(const UINT16 *source, int sourcewidth, int sourceshift)
{
+ int histo[256] = { 0 };
int minval = 0xff;
int maxval = 0x00;
- int avgval = 0x00;
- int diff;
+ int subtract;
+ int peakval;
+ int result;
int x;
-
- /* compute minimum, maximum, and average values across the line */
+
+ /* compute a histogram of values */
for (x = 0; x < sourcewidth; x++)
{
UINT8 yval = source[x] >> sourceshift;
- minval = MIN(yval, minval);
- maxval = MAX(yval, maxval);
- avgval += yval;
+ 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);
}
- avgval /= sourcewidth;
- diff = maxval - minval;
+
+ /* 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;
- /* if there's a spread of at least 0x20, and the average is above 3/4 of the center, call it good */
- return (diff >= 0x20) && (avgval >= minval + 3 * diff / 4);
+ /* 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
}