mirror of
https://github.com/holub/mame
synced 2025-07-06 10:29:38 +03:00
Split out Philips code parsing into a separate utility module.
Rewrote Philips code parsing to be clock based. Updated makemeta to call the new function.
This commit is contained in:
parent
bdbc3226c6
commit
d256dc7e88
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1023,6 +1023,8 @@ src/lib/util/unicode.c svneol=native#text/plain
|
||||
src/lib/util/unicode.h svneol=native#text/plain
|
||||
src/lib/util/unzip.c svneol=native#text/plain
|
||||
src/lib/util/unzip.h svneol=native#text/plain
|
||||
src/lib/util/vbiparse.c svneol=native#text/plain
|
||||
src/lib/util/vbiparse.h svneol=native#text/plain
|
||||
src/lib/util/xmlfile.c svneol=native#text/plain
|
||||
src/lib/util/xmlfile.h svneol=native#text/plain
|
||||
src/lib/zlib/Makefile svneol=native#text/plain
|
||||
|
@ -44,6 +44,7 @@ UTILOBJS = \
|
||||
$(LIBOBJ)/util/sha1.o \
|
||||
$(LIBOBJ)/util/unicode.o \
|
||||
$(LIBOBJ)/util/unzip.o \
|
||||
$(LIBOBJ)/util/vbiparse.o \
|
||||
$(LIBOBJ)/util/xmlfile.o \
|
||||
|
||||
$(OBJ)/libutil.a: $(UTILOBJS)
|
||||
|
137
src/lib/util/vbiparse.c
Normal file
137
src/lib/util/vbiparse.c
Normal file
@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
|
||||
vbiparse.c
|
||||
|
||||
Parse Philips codes and other data from VBI lines.
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "aviio.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define MAX_SOURCE_WIDTH 1024
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
vbi_parse_line - parse a Philips code from a
|
||||
line of video data
|
||||
-------------------------------------------------*/
|
||||
|
||||
int vbi_parse_line(const UINT16 *source, int sourcewidth, int sourceshift, int expectedbits, UINT8 *result)
|
||||
{
|
||||
UINT8 srcabs[MAX_SOURCE_WIDTH];
|
||||
UINT8 min, max, mid, srcabsval;
|
||||
double clock, bestclock;
|
||||
int x, firstedge;
|
||||
int besterr;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* exact match? */
|
||||
if (srcabs[curbit + 0] != srcabs[curbit + 1])
|
||||
continue;
|
||||
|
||||
/* off-by-one? */
|
||||
if (srcabs[curbit + 1 + 0] != srcabs[curbit + 1 + 1] || srcabs[curbit - 1 + 0] != srcabs[curbit - 1 + 1])
|
||||
{
|
||||
/* only continue if we're still in the running */
|
||||
if (++error < besterr)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* anything else fails immediately */
|
||||
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 leftbit = firstedge + ((double)x - 0.25) * bestclock;
|
||||
int rightbit = firstedge + ((double)x + 0.25) * bestclock;
|
||||
int left = srcabs[leftbit];
|
||||
int right = srcabs[rightbit];
|
||||
|
||||
/* all bits should be marked by transitions; fail if we don't get one */
|
||||
if (left == right)
|
||||
return 0;
|
||||
result[x] = (left < right);
|
||||
}
|
||||
return expectedbits;
|
||||
}
|
25
src/lib/util/vbiparse.h
Normal file
25
src/lib/util/vbiparse.h
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
|
||||
vbiparse.h
|
||||
|
||||
Parse Philips codes and other data from VBI lines.
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __VBIPARSE_H__
|
||||
#define __VBIPARSE_H__
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
/* parse a Philips code from a line of video data */
|
||||
int vbi_parse_line(const UINT16 *source, int sourcewidth, int sourceshift, int expectedbits, UINT8 *result);
|
||||
|
||||
#endif /* __VBIPARSE_H__ */
|
@ -28,6 +28,7 @@
|
||||
#include <ctype.h>
|
||||
#include "aviio.h"
|
||||
#include "bitmap.h"
|
||||
#include "vbiparse.h"
|
||||
|
||||
|
||||
|
||||
@ -59,85 +60,6 @@ struct _pattern_data
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
parse_line - parse a Philips code from a
|
||||
line of video data
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int parse_line(bitmap_t *bitmap, int line, int expected_bits, UINT8 *result)
|
||||
{
|
||||
const UINT16 *source = BITMAP_ADDR16(bitmap, line, 0);
|
||||
int x, edges = 0, bits = 0;
|
||||
int minwidth = 1000;
|
||||
UINT8 bit[720];
|
||||
int edge[720];
|
||||
int error = 0;
|
||||
|
||||
/* clamp expected bits */
|
||||
expected_bits *= 2;
|
||||
if (expected_bits > ARRAY_LENGTH(edge) - 1)
|
||||
expected_bits = ARRAY_LENGTH(edge) - 1;
|
||||
|
||||
/* find the edges in the line */
|
||||
for (x = 1; x < bitmap->width && edges < ARRAY_LENGTH(edge); x++)
|
||||
if (source[x] >= 0xc000 && source[x - 1] < 0xc000)
|
||||
edge[edges++] = x;
|
||||
else if (source[x] <= 0x4000 && source[x - 1] > 0x4000)
|
||||
edge[edges++] = x;
|
||||
|
||||
/* find the minimum width */
|
||||
for (x = 1; x < edges; x++)
|
||||
{
|
||||
int width = edge[x] - edge[x - 1];
|
||||
if (width > 3 && width < minwidth)
|
||||
minwidth = edge[x] - edge[x - 1];
|
||||
}
|
||||
|
||||
/* now generate the bits */
|
||||
for (x = 1; x < edges; x++)
|
||||
{
|
||||
int width = edge[x] - edge[x - 1];
|
||||
if (width > 3)
|
||||
{
|
||||
int count = (width > 3 * minwidth / 2) ? 2 : 1;
|
||||
while (count--)
|
||||
bit[bits++] = (source[edge[x - 1]] >= 0x8000) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* look for improperly paired bits in the sequence */
|
||||
if (bits < expected_bits)
|
||||
{
|
||||
/* look for two bits in a row of the same type on an even boundary */
|
||||
for (x = 0; x < bits; x += 2)
|
||||
if (bit[x] == bit[x + 1])
|
||||
break;
|
||||
|
||||
/* if we got something wrong, assume we're missing an opening 0 bit */
|
||||
if (x < bits)
|
||||
{
|
||||
memmove(&bit[1], &bit[0], bits);
|
||||
bit[0] = 0;
|
||||
bits++;
|
||||
}
|
||||
}
|
||||
|
||||
/* trailing bits are 0 */
|
||||
while (bits < expected_bits)
|
||||
bit[bits++] = 0;
|
||||
|
||||
/* output */
|
||||
for (x = 0; x < MIN(bits, expected_bits); x += 2)
|
||||
{
|
||||
static const UINT8 trans[4] = { 0x80, 1, 0, 0xff };
|
||||
result[x/2] = trans[(bit[x] << 1) | bit[x + 1]];
|
||||
if (result[x/2] > 1)
|
||||
error++;
|
||||
}
|
||||
return error ? -(bits / 2) : (bits / 2);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
output_meta - output a line of metadata
|
||||
-------------------------------------------------*/
|
||||
@ -227,23 +149,6 @@ static int generate_from_avi(const char *aviname)
|
||||
int prevwhite = white;
|
||||
int i;
|
||||
|
||||
{
|
||||
static FILE *f;
|
||||
int line;
|
||||
if (!f) f = fopen("temp.log", "w");
|
||||
fprintf(f, "\n\nFrame %d, field %d\n", frame, field);
|
||||
for (line = 0; line < 22; line++)
|
||||
{
|
||||
UINT16 *src = BITMAP_ADDR16(bitmap, line*2 + field, 0);
|
||||
int x;
|
||||
for (x = 0; x < bitmap->width; x++)
|
||||
fprintf(f, "%04X ", *src++);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
}
|
||||
|
||||
/* line 11 contains the white flag */
|
||||
white = 0;
|
||||
if (*BITMAP_ADDR16(bitmap, 11*2 + field, bitmap->width / 2) > 0x8000)
|
||||
@ -261,18 +166,18 @@ static int generate_from_avi(const char *aviname)
|
||||
|
||||
/* line 16 contains stop code and other interesting bits */
|
||||
line16 = 0;
|
||||
if (parse_line(bitmap, 16*2 + field, 24, bits) == 24)
|
||||
if (vbi_parse_line(BITMAP_ADDR16(bitmap, 16*2 + field, 0), bitmap->width, 8, 24, bits) == 24)
|
||||
for (i = 0; i < 24; i++)
|
||||
line16 = (line16 << 1) | bits[i];
|
||||
|
||||
/* line 17 and 18 contain frame/chapter/lead in/out encodings */
|
||||
line17 = 0;
|
||||
if (parse_line(bitmap, 17*2 + field, 24, bits) == 24)
|
||||
if (vbi_parse_line(BITMAP_ADDR16(bitmap, 17*2 + field, 0), bitmap->width, 8, 24, bits) == 24)
|
||||
for (i = 0; i < 24; i++)
|
||||
line17 = (line17 << 1) | bits[i];
|
||||
|
||||
line18 = 0;
|
||||
if (parse_line(bitmap, 18*2 + field, 24, bits) == 24)
|
||||
if (vbi_parse_line(BITMAP_ADDR16(bitmap, 18*2 + field, 0), bitmap->width, 8, 24, bits) == 24)
|
||||
for (i = 0; i < 24; i++)
|
||||
line18 = (line18 << 1) | bits[i];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user