Added flags to the metadata entries, encoded in the top bit. Right now

it is a no-op, but eventually will be used to indicate which bits of
metadata are included in the overall checksum.
This commit is contained in:
Aaron Giles 2009-03-05 07:35:24 +00:00
parent 6a0e1fcfe0
commit e8c09b35f6
8 changed files with 65 additions and 30 deletions

View File

@ -1331,7 +1331,7 @@ static void init_disc(const device_config *device)
fatalerror("Laserdisc video must be compressed with the A/V codec!");
/* read the metadata */
err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
fatalerror("Non-A/V CHD file specified");
@ -1350,7 +1350,7 @@ static void init_disc(const device_config *device)
/* allocate memory for the precomputed per-frame metadata */
ldcore->vbidata = auto_malloc(totalhunks * VBI_PACKED_BYTES);
err = chd_get_metadata(ldcore->disc, AV_LD_METADATA_TAG, 0, ldcore->vbidata, totalhunks * VBI_PACKED_BYTES, &vbilength, NULL);
err = chd_get_metadata(ldcore->disc, AV_LD_METADATA_TAG, 0, ldcore->vbidata, totalhunks * VBI_PACKED_BYTES, &vbilength, NULL, NULL);
if (err != CHDERR_NONE || vbilength != totalhunks * VBI_PACKED_BYTES)
fatalerror("Precomputed VBI metadata missing or incorrect size");
}

View File

@ -549,7 +549,7 @@ static chd_error parse_metadata(chd_file *chd, cdrom_toc *toc)
char type[11], subtype[11];
/* fetch the metadata for this track */
err = chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
break;
@ -583,7 +583,7 @@ static chd_error parse_metadata(chd_file *chd, cdrom_toc *toc)
return CHDERR_NONE;
/* look for old-style metadata */
err = chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, oldmetadata, sizeof(oldmetadata), NULL, NULL);
err = chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, oldmetadata, sizeof(oldmetadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
return err;

View File

@ -114,6 +114,7 @@ struct _metadata_entry
UINT64 prev; /* offset within the file of the previous header */
UINT32 length; /* length of the metadata */
UINT32 metatag; /* metadata tag */
UINT8 flags; /* flag bits */
};
@ -1120,7 +1121,7 @@ chd_error chd_async_complete(chd_file *chd)
of the given type
-------------------------------------------------*/
chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag)
chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
{
metadata_entry metaentry;
chd_error err;
@ -1168,6 +1169,8 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex,
*resultlen = metaentry.length;
if (resulttag != NULL)
*resulttag = metaentry.metatag;
if (resultflags != NULL)
*resultflags = metaentry.flags;
return CHDERR_NONE;
}
@ -1177,7 +1180,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex,
of the given type
-------------------------------------------------*/
chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen)
chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen, UINT8 flags)
{
UINT8 raw_meta_header[METADATA_HEADER_SIZE];
metadata_entry metaentry;
@ -1196,6 +1199,10 @@ chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, cons
/* must write at least 1 byte */
if (inputlen < 1)
return CHDERR_INVALID_PARAMETER;
/* no more than 16MB */
if (inputlen >= 16 * 1024 * 1024)
return CHDERR_INVALID_PARAMETER;
/* wait for any pending async operations */
wait_for_pending_async(chd);
@ -1232,7 +1239,7 @@ chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, cons
/* now build us a new entry */
put_bigendian_uint32(&raw_meta_header[0], metatag);
put_bigendian_uint32(&raw_meta_header[4], inputlen);
put_bigendian_uint32(&raw_meta_header[4], (inputlen & 0x00ffffff) | (flags << 24));
put_bigendian_uint64(&raw_meta_header[8], (err == CHDERR_NONE) ? metaentry.next : 0);
/* write out the new header */
@ -1266,13 +1273,14 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest)
{
UINT32 metatag, metasize, metaindex;
UINT8 metabuffer[1024];
UINT8 metaflags;
chd_error err;
/* clone the metadata */
for (metaindex = 0; ; metaindex++)
{
/* fetch the next piece of metadata */
err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, metabuffer, sizeof(metabuffer), &metasize, &metatag);
err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, metabuffer, sizeof(metabuffer), &metasize, &metatag, &metaflags);
if (err != CHDERR_NONE)
{
if (err == CHDERR_METADATA_NOT_FOUND)
@ -1284,7 +1292,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest)
if (metasize <= sizeof(metabuffer))
{
/* write it to the target */
err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, metabuffer, metasize);
err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, metabuffer, metasize, metaflags);
if (err != CHDERR_NONE)
break;
}
@ -1300,7 +1308,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest)
}
/* re-read the whole thing */
err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, allocbuffer, metasize, &metasize, &metatag);
err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, allocbuffer, metasize, &metasize, &metatag, &metaflags);
if (err != CHDERR_NONE)
{
free(allocbuffer);
@ -1308,7 +1316,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest)
}
/* write it to the target */
err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, allocbuffer, metasize);
err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, allocbuffer, metasize, metaflags);
free(allocbuffer);
if (err != CHDERR_NONE)
break;
@ -2364,6 +2372,10 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai
metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
/* checksum is encoded as the high bit of length */
metaentry->flags = metaentry->length >> 24;
metaentry->length &= 0x00ffffff;
/* if we got a match, proceed */
if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
@ -2431,6 +2443,7 @@ static chd_error metadata_set_previous_next(chd_file *chd, UINT64 prevoffset, UI
static chd_error metadata_set_length(chd_file *chd, UINT64 offset, UINT32 length)
{
UINT8 raw_meta_header[METADATA_HEADER_SIZE];
UINT32 oldlength;
UINT32 count;
/* read the raw header */
@ -2439,7 +2452,9 @@ static chd_error metadata_set_length(chd_file *chd, UINT64 offset, UINT32 length
if (count != sizeof(raw_meta_header))
return CHDERR_READ_ERROR;
/* update the length at offset 4 */
/* update the length at offset 4, preserving the flags in the upper byte */
oldlength = get_bigendian_uint32(&raw_meta_header[4]);
length = (length & 0x00ffffff) | (oldlength & 0xff000000);
put_bigendian_uint32(&raw_meta_header[4], length);
/* write the raw header */
@ -2867,7 +2882,7 @@ static chd_error av_codec_postinit(chd_file *chd)
return CHDERR_OPERATION_PENDING;
/* get the metadata */
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
return err;

View File

@ -76,6 +76,23 @@
[100] UINT8 parentsha1[20];// SHA1 checksum of parent file
[120] (V3 header length)
Proposed V4 header:
[ 0] char tag[8]; // 'MComprHD'
[ 8] UINT32 length; // length of header (including tag and length fields)
[ 12] UINT32 version; // drive format version
[ 16] UINT32 flags; // flags (see below)
[ 20] UINT32 compression; // compression type
[ 24] UINT32 totalhunks; // total # of hunks represented
[ 28] UINT64 logicalbytes; // logical size of the data (in bytes)
[ 36] UINT64 metaoffset; // offset to the first blob of metadata
[ 44] UINT32 hunkbytes; // number of bytes per hunk
[ 48] UINT8 sha1[20]; // combined raw+meta SHA1
[ 68] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent
[ 88] UINT8 rawsha1[20]; // raw data SHA1
[108] UINT8 metasha1[20]; // metadata SHA1
[128] (V4 header length)
Flags:
0x00000001 - set if this drive has a parent
0x00000002 - set if this drive allows writes
@ -117,6 +134,9 @@
#define CHDMETATAG_WILDCARD 0
#define CHD_METAINDEX_APPEND ((UINT32)-1)
/* metadata flags */
#define CHD_MDFLAGS_CHECKSUM 0x01 /* indicates data is checksummed */
/* standard hard disk metadata */
#define HARD_DISK_METADATA_TAG 0x47444444 /* 'GDDD' */
#define HARD_DISK_METADATA_FORMAT "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d"
@ -271,10 +291,10 @@ chd_error chd_async_complete(chd_file *chd);
/* ----- metadata management ----- */
/* get indexed metadata of a particular sort */
chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag);
chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags);
/* set indexed metadata of a particular sort */
chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen);
chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen, UINT8 flags);
/* clone all of the metadata from one CHD to another */
chd_error chd_clone_metadata(chd_file *source, chd_file *dest);

View File

@ -49,7 +49,7 @@ hard_disk_file *hard_disk_open(chd_file *chd)
return NULL;
/* read the hard disk metadata */
err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
return NULL;

View File

@ -309,7 +309,7 @@ static int do_createhd(int argc, char *argv[], int param)
/* write the metadata */
sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding hard disk metadata: %s\n", chd_error_string(err));
@ -480,7 +480,7 @@ static int do_createcd(int argc, char *argv[], int param)
sprintf(metadata, CDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(&toc.tracks[i]),
cdrom_get_subtype_string(&toc.tracks[i]), toc.tracks[i].frames);
err = chd_set_metadata(chd, CDROM_TRACK_METADATA_TAG, i, metadata, strlen(metadata) + 1);
err = chd_set_metadata(chd, CDROM_TRACK_METADATA_TAG, i, metadata, strlen(metadata) + 1, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding CD-ROM metadata: %s\n", chd_error_string(err));
@ -902,7 +902,7 @@ static int do_createav(int argc, char *argv[], int param)
/* write the metadata */
sprintf(metadata, AV_METADATA_FORMAT, fps_times_1million / 1000000, fps_times_1million % 1000000, width, height, interlaced, channels, rate);
err = chd_set_metadata(chd, AV_METADATA_TAG, 0, metadata, strlen(metadata) + 1);
err = chd_set_metadata(chd, AV_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding AV metadata: %s\n", chd_error_string(err));
@ -959,7 +959,7 @@ static int do_createav(int argc, char *argv[], int param)
/* write the final metadata */
if (ldframedata != NULL)
{
err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, ldframedata, numframes * VBI_PACKED_BYTES);
err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, ldframedata, numframes * VBI_PACKED_BYTES, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding AVLD metadata: %s\n", chd_error_string(err));
@ -1048,7 +1048,7 @@ static int do_createblankhd(int argc, char *argv[], int param)
/* write the metadata */
sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding hard disk metadata: %s\n", chd_error_string(err));
@ -1478,7 +1478,7 @@ static int do_extractav(int argc, char *argv[], int param)
header = chd_get_header(chd);
/* get the metadata */
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(err));
@ -1806,7 +1806,7 @@ static int do_fixavdata(int argc, char *argv[], int param)
header = *chd_get_header(chd);
/* get the metadata */
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(err));
@ -1849,7 +1849,7 @@ static int do_fixavdata(int argc, char *argv[], int param)
}
/* read the metadata */
err = chd_get_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, &actlength, NULL);
err = chd_get_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, &actlength, NULL, NULL);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error getting VBI metadata: %s\n", chd_error_string(err));
@ -1967,7 +1967,7 @@ static int do_fixavdata(int argc, char *argv[], int param)
}
/* write new metadata */
err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES);
err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error adding AVLD metadata: %s\n", chd_error_string(err));
@ -2071,7 +2071,7 @@ static int do_info(int argc, char *argv[], int param)
UINT32 metatag, metasize;
/* get the indexed metadata item; stop when we hit an error */
err = chd_get_metadata(chd, CHDMETATAG_WILDCARD, i, metadata, sizeof(metadata), &metasize, &metatag);
err = chd_get_metadata(chd, CHDMETATAG_WILDCARD, i, metadata, sizeof(metadata), &metasize, &metatag, NULL);
if (err != CHDERR_NONE)
break;
@ -2484,7 +2484,7 @@ static int do_setchs(int argc, char *argv[], int param)
}
/* get the hard disk metadata */
err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (err != CHDERR_NONE || sscanf(metadata, HARD_DISK_METADATA_FORMAT, &oldcyls, &oldhds, &oldsecs, &oldsecsize) != 4)
{
fprintf(stderr, "CHD file '%s' is not a hard disk!\n", inoutfile);
@ -2494,7 +2494,7 @@ static int do_setchs(int argc, char *argv[], int param)
/* write our own */
sprintf(metadata, HARD_DISK_METADATA_FORMAT, cyls, hds, secs, oldsecsize);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1);
err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
if (err != CHDERR_NONE)
{
fprintf(stderr, "Error writing new metadata to CHD file: %s\n", chd_error_string(err));

View File

@ -177,7 +177,7 @@ static chd_file *open_chd(const char *filename, movie_info *info)
}
/* get the metadata */
chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (chderr != CHDERR_NONE)
{
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr));

View File

@ -179,7 +179,7 @@ static void *open_chd(const char *filename, movie_info *info)
}
/* get the metadata */
chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL);
chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
if (chderr != CHDERR_NONE)
{
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr));