mirror of
https://github.com/holub/mame
synced 2025-05-29 00:53:09 +03:00
Move all-0 detection to the write path. Use hunk_info on the
compression path to detect whether the write went through.
This commit is contained in:
parent
397de27f0c
commit
633f8e497f
@ -910,6 +910,20 @@ chd_error chd_file::write_hunk(UINT32 hunknum, const void *buffer)
|
|||||||
// if not, allocate one now
|
// if not, allocate one now
|
||||||
if (rawentry == 0)
|
if (rawentry == 0)
|
||||||
{
|
{
|
||||||
|
// first make sure we need to allocate it
|
||||||
|
bool all_zeros = true;
|
||||||
|
const UINT32 *scan = reinterpret_cast<const UINT32 *>(buffer);
|
||||||
|
for (UINT32 index = 0; index < m_hunkbytes / 4; index++)
|
||||||
|
if (scan[index] != 0)
|
||||||
|
{
|
||||||
|
all_zeros = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's all zeros, do nothing more
|
||||||
|
if (all_zeros)
|
||||||
|
return CHDERR_NONE;
|
||||||
|
|
||||||
// append new data to the end of the file, aligning the first chunk
|
// append new data to the end of the file, aligning the first chunk
|
||||||
rawentry = file_append(buffer, m_hunkbytes, m_hunkbytes) / m_hunkbytes;
|
rawentry = file_append(buffer, m_hunkbytes, m_hunkbytes) / m_hunkbytes;
|
||||||
|
|
||||||
@ -2451,25 +2465,16 @@ chd_error chd_file_compressor::compress_continue(double &progress, double &ratio
|
|||||||
// if we're uncompressed, use regular writes
|
// if we're uncompressed, use regular writes
|
||||||
else if (!compressed())
|
else if (!compressed())
|
||||||
{
|
{
|
||||||
bool skip = true;
|
chd_error err = write_hunk(item.m_hunknum, item.m_data);
|
||||||
|
if (err != CHDERR_NONE)
|
||||||
// see if it's all 0
|
return err;
|
||||||
for (UINT32 offs = 0; offs < m_hunkbytes && skip; offs++)
|
|
||||||
if (item.m_data[offs] != 0)
|
// writes of all-0 data don't actually take space, so see if we count this
|
||||||
skip = false;
|
chd_codec_type codec = CHD_CODEC_NONE;
|
||||||
|
UINT32 complen;
|
||||||
// see if it's in the parent map
|
hunk_info(item.m_hunknum, codec, complen);
|
||||||
if (!skip && m_parent != NULL && m_parent_map.find(item.m_hash[0].m_crc16, item.m_hash[0].m_sha1) != hashmap::NOT_FOUND)
|
if (codec == CHD_CODEC_NONE)
|
||||||
skip = true;
|
|
||||||
|
|
||||||
// write the block
|
|
||||||
if (!skip)
|
|
||||||
{
|
|
||||||
chd_error err = write_hunk(item.m_hunknum, item.m_data);
|
|
||||||
if (err != CHDERR_NONE)
|
|
||||||
return err;
|
|
||||||
m_total_out += m_hunkbytes;
|
m_total_out += m_hunkbytes;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for compressing, process the result
|
// for compressing, process the result
|
||||||
|
@ -82,9 +82,9 @@ struct _movie_info
|
|||||||
int samplerate;
|
int samplerate;
|
||||||
int channels;
|
int channels;
|
||||||
int interlaced;
|
int interlaced;
|
||||||
bitmap_yuy16 *bitmap;
|
bitmap_yuy16 bitmap;
|
||||||
INT16 * lsound;
|
dynamic_array<INT16> lsound;
|
||||||
INT16 * rsound;
|
dynamic_array<INT16> rsound;
|
||||||
UINT32 samples;
|
UINT32 samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,100 +143,53 @@ INLINE UINT32 sample_number_to_field(const movie_info *info, UINT32 samplenum, U
|
|||||||
CHD HANDLING
|
CHD HANDLING
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
chd_allocate_buffers - allocate buffers for
|
|
||||||
CHD I/O
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static int chd_allocate_buffers(movie_info *info)
|
|
||||||
{
|
|
||||||
/* allocate a bitmap */
|
|
||||||
info->bitmap = new(std::nothrow) bitmap_yuy16(info->width, info->height);
|
|
||||||
if (info->bitmap == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Out of memory creating %dx%d bitmap\n", info->width, info->height);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate sound buffers */
|
|
||||||
info->lsound = (INT16 *)malloc(info->samplerate * sizeof(*info->lsound));
|
|
||||||
info->rsound = (INT16 *)malloc(info->samplerate * sizeof(*info->rsound));
|
|
||||||
if (info->lsound == NULL || info->rsound == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Out of memory allocating sound buffers of %d bytes\n", (INT32)(info->samplerate * sizeof(*info->rsound)));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
chd_free_buffers - release buffers for
|
|
||||||
CHD I/O
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static void chd_free_buffers(movie_info *info)
|
|
||||||
{
|
|
||||||
delete info->bitmap;
|
|
||||||
if (info->lsound != NULL)
|
|
||||||
free(info->lsound);
|
|
||||||
if (info->rsound != NULL)
|
|
||||||
free(info->rsound);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
open_chd - open a CHD file and return
|
open_chd - open a CHD file and return
|
||||||
information about it
|
information about it
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static chd_file *open_chd(const char *filename, movie_info *info)
|
static chd_error open_chd(chd_file &file, const char *filename, movie_info &info)
|
||||||
{
|
{
|
||||||
int fps, fpsfrac, width, height, interlaced, channels, rate;
|
|
||||||
char metadata[256];
|
|
||||||
chd_error chderr;
|
|
||||||
chd_file *chd;
|
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
chderr = chd_open(filename, CHD_OPEN_READ, NULL, &chd);
|
chd_error chderr = file.open(filename);
|
||||||
if (chderr != CHDERR_NONE)
|
if (chderr != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error opening CHD file: %s\n", chd_error_string(chderr));
|
fprintf(stderr, "Error opening CHD file: %s\n", chd_error_string(chderr));
|
||||||
return NULL;
|
return chderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the metadata */
|
/* get the metadata */
|
||||||
chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL);
|
astring metadata;
|
||||||
|
chderr = chd.read_metadata(chd, AV_METADATA_TAG, 0, metadata);
|
||||||
if (chderr != CHDERR_NONE)
|
if (chderr != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr));
|
fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr));
|
||||||
chd_close(chd);
|
return chderr;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract the info */
|
/* extract the info */
|
||||||
|
int fps, fpsfrac, width, height, interlaced, channels, rate;
|
||||||
if (sscanf(metadata, AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7)
|
if (sscanf(metadata, AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Improperly formatted metadata\n");
|
fprintf(stderr, "Improperly formatted metadata\n");
|
||||||
chd_close(chd);
|
return CHDERR_INVALID_DATA;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract movie info */
|
/* extract movie info */
|
||||||
info->iframerate = fps * 1000000 + fpsfrac;
|
info.iframerate = fps * 1000000 + fpsfrac;
|
||||||
info->framerate = info->iframerate / 1000000.0;
|
info.framerate = info.iframerate / 1000000.0;
|
||||||
info->numfields = chd_get_header(chd)->totalhunks;
|
info.numfields = file->hunk_count();
|
||||||
info->width = width;
|
info.width = width;
|
||||||
info->height = height;
|
info.height = height;
|
||||||
info->interlaced = interlaced;
|
info.interlaced = interlaced;
|
||||||
info->samplerate = rate;
|
info.samplerate = rate;
|
||||||
info->channels = channels;
|
info.channels = channels;
|
||||||
|
|
||||||
/* allocate buffers */
|
/* allocate buffers */
|
||||||
if (!chd_allocate_buffers(info))
|
info.bitmap.resize(info.width, info.height);
|
||||||
return NULL;
|
info.lsound.resize(info.samplerate);
|
||||||
|
info.rsound.resize(info.samplerate);
|
||||||
return chd;
|
return CHDERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -244,46 +197,34 @@ static chd_file *open_chd(const char *filename, movie_info *info)
|
|||||||
create_chd - create a new CHD file
|
create_chd - create a new CHD file
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
static chd_file *create_chd(const char *filename, chd_file *source, const movie_info *info)
|
static chd_error create_chd(chd_compressor &file, const char *filename, chd_file &source, const movie_info &info)
|
||||||
{
|
{
|
||||||
const chd_header *srcheader = chd_get_header(source);
|
|
||||||
chd_error chderr;
|
|
||||||
chd_file *chd;
|
|
||||||
|
|
||||||
/* create the file */
|
/* create the file */
|
||||||
chderr = chd_create(filename, srcheader->logicalbytes, srcheader->hunkbytes, CHDCOMPRESSION_AV, NULL);
|
chd_codec_type compression = { CHD_CODEC_AVHUFF };
|
||||||
|
chd_error chderr = file.create(filename, source.logical_bytes(), source.hunk_bytes(), source.unit_bytes(), compression);
|
||||||
if (chderr != CHDERR_NONE)
|
if (chderr != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error creating new CHD file: %s\n", chd_error_string(chderr));
|
fprintf(stderr, "Error creating new CHD file: %s\n", chd_error_string(chderr));
|
||||||
return NULL;
|
return chderr;
|
||||||
}
|
|
||||||
|
|
||||||
/* open the file */
|
|
||||||
chderr = chd_open(filename, CHD_OPEN_READWRITE, NULL, &chd);
|
|
||||||
if (chderr != CHDERR_NONE)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error opening new CHD file: %s\n", chd_error_string(chderr));
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clone the metadata */
|
/* clone the metadata */
|
||||||
chderr = chd_clone_metadata(source, chd);
|
chderr = file.clone_all_metadata(source);
|
||||||
if (chderr != CHDERR_NONE)
|
if (chderr != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error cloning metadata: %s\n", chd_error_string(chderr));
|
fprintf(stderr, "Error cloning metadata: %s\n", chd_error_string(chderr));
|
||||||
chd_close(chd);
|
return chderr;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* begin compressing */
|
/* begin compressing */
|
||||||
chderr = chd_compress_begin(chd);
|
chderr = file.compress_begin();
|
||||||
if (chderr != CHDERR_NONE)
|
if (chderr != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error beginning compression: %s\n", chd_error_string(chderr));
|
fprintf(stderr, "Error beginning compression: %s\n", chd_error_string(chderr));
|
||||||
return NULL;
|
return chderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return chd;
|
return CHDERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -549,7 +490,6 @@ int main(int argc, char *argv[])
|
|||||||
const char *srcfilename;
|
const char *srcfilename;
|
||||||
const char *dstfilename;
|
const char *dstfilename;
|
||||||
double offset, slope;
|
double offset, slope;
|
||||||
chd_file *srcfile;
|
|
||||||
chd_file *dstfile;
|
chd_file *dstfile;
|
||||||
|
|
||||||
/* verify arguments */
|
/* verify arguments */
|
||||||
@ -570,8 +510,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* open the source file */
|
/* open the source file */
|
||||||
srcfile = open_chd(srcfilename, &info);
|
chd_file srcfile;
|
||||||
if (srcfile == NULL)
|
chd_error err = open_chd(srcfile, srcfilename, info);
|
||||||
|
if (err != CHDERR_NONE)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to open file '%s'\n", srcfilename);
|
fprintf(stderr, "Unable to open file '%s'\n", srcfilename);
|
||||||
return 1;
|
return 1;
|
||||||
@ -604,7 +545,7 @@ int main(int argc, char *argv[])
|
|||||||
UINT32 fieldnum;
|
UINT32 fieldnum;
|
||||||
|
|
||||||
/* open the destination file */
|
/* open the destination file */
|
||||||
dstfile = create_chd(dstfilename, srcfile, &info);
|
err = create_chd(dstfile, dstfilename, srcfile, info);
|
||||||
if (dstfile == NULL)
|
if (dstfile == NULL)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to create file '%s'\n", dstfilename);
|
fprintf(stderr, "Unable to create file '%s'\n", dstfilename);
|
||||||
|
Loading…
Reference in New Issue
Block a user