summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
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
}