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 @@ -15,6 +15,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]++; } - avgval /= sourcewidth; - diff = maxval - minval; + + /* 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; - /* 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); + /* 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 } diff --git a/src/tools/ldverify.c b/src/tools/ldverify.c index baa28b74bdf..38430a7e1c2 100644 --- a/src/tools/ldverify.c +++ b/src/tools/ldverify.c @@ -310,7 +310,7 @@ static void verify_video(int frame, bitmap_t *bitmap) /* output status */ if (frame % 10 == 0 && fieldnum == 0) - printf("%6d.%d...\r", frame, fieldnum); + fprintf(stderr, "%6d.%d...\r", frame, fieldnum); /* parse the VBI data */ vbi_parse_all(BITMAP_ADDR16(bitmap, fieldnum, 0), bitmap->rowpixels * 2, bitmap->width, 8, &metadata); @@ -371,14 +371,16 @@ static void verify_video(int frame, bitmap_t *bitmap) /* if this is the first frame, make sure it's 1 */ if (video_last_frame == -1) { - if (framenum == 1) + if (framenum == 0) + printf("%6d.%d: detected frame 0\n", frame, fieldnum); + else if (framenum == 1) printf("%6d.%d: detected frame 1\n", frame, fieldnum); else - printf("%6d.%d: first frame number is not 1 (%d) (ERROR)\n", frame, fieldnum, framenum); + printf("%6d.%d: first frame number is not 0 or 1 (%d) (ERROR)\n", frame, fieldnum, framenum); } - /* print an update every 1000 frames */ - if (framenum % 1000 == 0) + /* print an update every 10000 frames */ + if (framenum != 0 && framenum % 10000 == 0) printf("%6d.%d: detected frame %d\n", frame, fieldnum, framenum); /* if this frame is not consecutive, it's an error */ @@ -464,6 +466,10 @@ static void verify_video_final(int frame, bitmap_t *bitmap) { int fields_per_frame = (bitmap->height >= 288) ? 2 : 1; int field = frame * fields_per_frame; + + /* did we ever see any white flags? */ + if (video_first_whitefield == -1) + printf("Track %6d.%d: never saw any white flags; no cadence detection done (WARNING)\n", field / fields_per_frame, 0); /* did we ever see any lead-out? */ if (video_saw_leadin && !video_saw_leadout)