mirror of
https://github.com/holub/mame
synced 2025-06-16 01:09:09 +03:00
util/chd.cpp, util/chdcodec.cpp: Added a safer way to let codecs do special stuff with hunks.
This commit is contained in:
parent
ec9aec11be
commit
ad459a9025
@ -38,7 +38,7 @@ static char const *const hd_option_spec =
|
|||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DEFINE_DEVICE_TYPE(HARDDISK, harddisk_image_device, "harddisk_image", "Harddisk")
|
DEFINE_DEVICE_TYPE(HARDDISK, harddisk_image_device, "harddisk_image", "Hard disk")
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// harddisk_image_base_device - constructor
|
// harddisk_image_base_device - constructor
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
||||||
laserdsc.c
|
|
||||||
|
|
||||||
Core laserdisc player implementation.
|
Core laserdisc player implementation.
|
||||||
|
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
@ -321,15 +319,15 @@ void laserdisc_device::device_start()
|
|||||||
void laserdisc_device::device_stop()
|
void laserdisc_device::device_stop()
|
||||||
{
|
{
|
||||||
// make sure all async operations have completed
|
// make sure all async operations have completed
|
||||||
if (m_disc != nullptr)
|
if (m_disc)
|
||||||
osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10);
|
osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10);
|
||||||
|
|
||||||
// free any textures and palettes
|
// free any textures and palettes
|
||||||
if (m_videotex != nullptr)
|
if (m_videotex)
|
||||||
machine().render().texture_free(m_videotex);
|
machine().render().texture_free(m_videotex);
|
||||||
if (m_videopalette != nullptr)
|
if (m_videopalette)
|
||||||
m_videopalette->deref();
|
m_videopalette->deref();
|
||||||
if (m_overtex != nullptr)
|
if (m_overtex)
|
||||||
machine().render().texture_free(m_overtex);
|
machine().render().texture_free(m_overtex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +341,7 @@ void laserdisc_device::device_reset()
|
|||||||
// attempt to wire up the audio
|
// attempt to wire up the audio
|
||||||
m_stream->set_sample_rate(m_samplerate);
|
m_stream->set_sample_rate(m_samplerate);
|
||||||
|
|
||||||
// set up the general ld
|
// set up the general LD
|
||||||
m_audiosquelch = 3;
|
m_audiosquelch = 3;
|
||||||
m_videosquelch = 1;
|
m_videosquelch = 1;
|
||||||
m_fieldnum = 0;
|
m_fieldnum = 0;
|
||||||
@ -729,10 +727,10 @@ void laserdisc_device::init_disc()
|
|||||||
m_fps_times_1million = 59940000;
|
m_fps_times_1million = 59940000;
|
||||||
m_samplerate = 48000;
|
m_samplerate = 48000;
|
||||||
|
|
||||||
// get the disc metadata and extract the ld
|
// get the disc metadata and extract the LD
|
||||||
m_chdtracks = 0;
|
m_chdtracks = 0;
|
||||||
m_maxtrack = VIRTUAL_LEAD_IN_TRACKS + MAX_TOTAL_TRACKS + VIRTUAL_LEAD_OUT_TRACKS;
|
m_maxtrack = VIRTUAL_LEAD_IN_TRACKS + MAX_TOTAL_TRACKS + VIRTUAL_LEAD_OUT_TRACKS;
|
||||||
if (m_disc != nullptr)
|
if (m_disc)
|
||||||
{
|
{
|
||||||
// require the A/V codec and nothing else
|
// require the A/V codec and nothing else
|
||||||
if (m_disc->compression(0) != CHD_CODEC_AVHUFF || m_disc->compression(1) != CHD_CODEC_NONE)
|
if (m_disc->compression(0) != CHD_CODEC_AVHUFF || m_disc->compression(1) != CHD_CODEC_NONE)
|
||||||
@ -1078,7 +1076,7 @@ void laserdisc_device::read_track_data()
|
|||||||
void *laserdisc_device::read_async_static(void *param, int threadid)
|
void *laserdisc_device::read_async_static(void *param, int threadid)
|
||||||
{
|
{
|
||||||
laserdisc_device &ld = *reinterpret_cast<laserdisc_device *>(param);
|
laserdisc_device &ld = *reinterpret_cast<laserdisc_device *>(param);
|
||||||
ld.m_readresult = ld.m_disc->read_hunk(ld.m_queued_hunknum, nullptr);
|
ld.m_readresult = ld.m_disc->codec_process_hunk(ld.m_queued_hunknum);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
||||||
laserdsc.h
|
|
||||||
|
|
||||||
Core laserdisc player implementation.
|
Core laserdisc player implementation.
|
||||||
|
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
@ -15,8 +13,9 @@
|
|||||||
|
|
||||||
#include "emupal.h"
|
#include "emupal.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "vbiparse.h"
|
|
||||||
#include "avhuff.h"
|
#include "avhuff.h"
|
||||||
|
#include "vbiparse.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
@ -98,7 +97,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// delegates
|
// delegates
|
||||||
typedef device_delegate<chd_file *(void)> get_disc_delegate;
|
typedef device_delegate<chd_file * ()> get_disc_delegate;
|
||||||
typedef device_delegate<void (int samplerate, int samples, const int16_t *ch0, const int16_t *ch1)> audio_delegate;
|
typedef device_delegate<void (int samplerate, int samples, const int16_t *ch0, const int16_t *ch1)> audio_delegate;
|
||||||
|
|
||||||
laserdisc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
laserdisc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
@ -892,6 +892,105 @@ void chd_file::close()
|
|||||||
m_cachehunk = ~0;
|
m_cachehunk = ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::error_condition chd_file::codec_process_hunk(uint32_t hunknum)
|
||||||
|
{
|
||||||
|
// punt if no file
|
||||||
|
if (UNEXPECTED(!m_file))
|
||||||
|
return std::error_condition(error::NOT_OPEN);
|
||||||
|
|
||||||
|
// return an error if out of range
|
||||||
|
if (UNEXPECTED(hunknum >= m_hunkcount))
|
||||||
|
return std::error_condition(error::HUNK_OUT_OF_RANGE);
|
||||||
|
|
||||||
|
// wrap this for clean reporting
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// get a pointer to the map entry
|
||||||
|
switch (m_version)
|
||||||
|
{
|
||||||
|
// v3/v4 map entries
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
uint8_t const *const rawmap = &m_rawmap[16 * hunknum];
|
||||||
|
uint64_t const blockoffs = get_u64be(&rawmap[0]);
|
||||||
|
switch (rawmap[15] & V34_MAP_ENTRY_FLAG_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case V34_MAP_ENTRY_TYPE_COMPRESSED:
|
||||||
|
{
|
||||||
|
uint32_t const blocklen = get_u16be(&rawmap[12]) | (uint32_t(rawmap[14]) << 16);
|
||||||
|
std::error_condition err = file_read(blockoffs, &m_compressed[0], blocklen);
|
||||||
|
if (UNEXPECTED(err))
|
||||||
|
return err;
|
||||||
|
m_decompressor[0]->process(&m_compressed[0], blocklen);
|
||||||
|
return std::error_condition();
|
||||||
|
}
|
||||||
|
|
||||||
|
case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
|
||||||
|
case V34_MAP_ENTRY_TYPE_MINI:
|
||||||
|
return std::error_condition(error::UNSUPPORTED_FORMAT);
|
||||||
|
|
||||||
|
case V34_MAP_ENTRY_TYPE_SELF_HUNK:
|
||||||
|
return codec_process_hunk(blockoffs);
|
||||||
|
|
||||||
|
case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
|
||||||
|
if (UNEXPECTED(m_parent_missing))
|
||||||
|
return std::error_condition(error::REQUIRES_PARENT);
|
||||||
|
return m_parent->codec_process_hunk(blockoffs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// v5 map entries
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
if (UNEXPECTED(!compressed()))
|
||||||
|
return std::error_condition(error::UNSUPPORTED_FORMAT);
|
||||||
|
|
||||||
|
// compressed case
|
||||||
|
uint8_t const *const rawmap = &m_rawmap[m_mapentrybytes * hunknum];
|
||||||
|
uint32_t const blocklen = get_u24be(&rawmap[1]);
|
||||||
|
uint64_t const blockoffs = get_u48be(&rawmap[4]);
|
||||||
|
switch (rawmap[0])
|
||||||
|
{
|
||||||
|
case COMPRESSION_TYPE_0:
|
||||||
|
case COMPRESSION_TYPE_1:
|
||||||
|
case COMPRESSION_TYPE_2:
|
||||||
|
case COMPRESSION_TYPE_3:
|
||||||
|
{
|
||||||
|
std::error_condition err = file_read(blockoffs, &m_compressed[0], blocklen);
|
||||||
|
if (UNEXPECTED(err))
|
||||||
|
return err;
|
||||||
|
auto &decompressor = *m_decompressor[rawmap[0]];
|
||||||
|
decompressor.process(&m_compressed[0], blocklen);
|
||||||
|
return std::error_condition();
|
||||||
|
}
|
||||||
|
|
||||||
|
case COMPRESSION_NONE:
|
||||||
|
return std::error_condition(error::UNSUPPORTED_FORMAT);
|
||||||
|
|
||||||
|
case COMPRESSION_SELF:
|
||||||
|
return codec_process_hunk(blockoffs);
|
||||||
|
|
||||||
|
case COMPRESSION_PARENT:
|
||||||
|
if (UNEXPECTED(m_parent_missing))
|
||||||
|
return std::error_condition(error::REQUIRES_PARENT);
|
||||||
|
return m_parent->codec_process_hunk(blockoffs / (m_parent->hunk_bytes() / m_parent->unit_bytes()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get here, the map contained an unsupported block type
|
||||||
|
return std::error_condition(error::INVALID_DATA);
|
||||||
|
}
|
||||||
|
catch (std::error_condition const &err)
|
||||||
|
{
|
||||||
|
// just return errors
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fn std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
* @fn std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
||||||
*
|
*
|
||||||
@ -1045,7 +1144,7 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
|||||||
case COMPRESSION_PARENT:
|
case COMPRESSION_PARENT:
|
||||||
if (UNEXPECTED(m_parent_missing))
|
if (UNEXPECTED(m_parent_missing))
|
||||||
return std::error_condition(error::REQUIRES_PARENT);
|
return std::error_condition(error::REQUIRES_PARENT);
|
||||||
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
|
return m_parent->read_bytes(blockoffs * m_parent->unit_bytes(), dest, m_hunkbytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -334,6 +334,7 @@ public:
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
// read/write
|
// read/write
|
||||||
|
std::error_condition codec_process_hunk(uint32_t hunknum);
|
||||||
std::error_condition read_hunk(uint32_t hunknum, void *buffer);
|
std::error_condition read_hunk(uint32_t hunknum, void *buffer);
|
||||||
std::error_condition write_hunk(uint32_t hunknum, const void *buffer);
|
std::error_condition write_hunk(uint32_t hunknum, const void *buffer);
|
||||||
std::error_condition read_units(uint64_t unitnum, void *buffer, uint32_t count = 1);
|
std::error_condition read_units(uint64_t unitnum, void *buffer, uint32_t count = 1);
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
chdcodec.c
|
|
||||||
|
|
||||||
Codecs used by the CHD format
|
Codecs used by the CHD format
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -333,16 +331,16 @@ private:
|
|||||||
|
|
||||||
// ======================> chd_cd_compressor
|
// ======================> chd_cd_compressor
|
||||||
|
|
||||||
template<class BaseCompressor, class SubcodeCompressor>
|
template <class BaseCompressor, class SubcodeCompressor>
|
||||||
class chd_cd_compressor : public chd_compressor
|
class chd_cd_compressor : public chd_compressor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
chd_cd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_cd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_compressor(chd, hunkbytes, lossy),
|
: chd_compressor(chd, hunkbytes, lossy)
|
||||||
m_base_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy),
|
, m_base_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy)
|
||||||
m_subcode_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy),
|
, m_subcode_compressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy)
|
||||||
m_buffer(hunkbytes + (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA)
|
, m_buffer(hunkbytes + (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA)
|
||||||
{
|
{
|
||||||
// make sure the CHD's hunk size is an even multiple of the frame size
|
// make sure the CHD's hunk size is an even multiple of the frame size
|
||||||
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
||||||
@ -402,16 +400,16 @@ private:
|
|||||||
|
|
||||||
// ======================> chd_cd_decompressor
|
// ======================> chd_cd_decompressor
|
||||||
|
|
||||||
template<class BaseDecompressor, class SubcodeDecompressor>
|
template <class BaseDecompressor, class SubcodeDecompressor>
|
||||||
class chd_cd_decompressor : public chd_decompressor
|
class chd_cd_decompressor : public chd_decompressor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
chd_cd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_cd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_decompressor(chd, hunkbytes, lossy),
|
: chd_decompressor(chd, hunkbytes, lossy)
|
||||||
m_base_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy),
|
, m_base_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SECTOR_DATA, lossy)
|
||||||
m_subcode_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy),
|
, m_subcode_decompressor(chd, (hunkbytes / cdrom_file::FRAME_SIZE) * cdrom_file::MAX_SUBCODE_DATA, lossy)
|
||||||
m_buffer(hunkbytes)
|
, m_buffer(hunkbytes)
|
||||||
{
|
{
|
||||||
// make sure the CHD's hunk size is an even multiple of the frame size
|
// make sure the CHD's hunk size is an even multiple of the frame size
|
||||||
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
||||||
@ -490,6 +488,7 @@ public:
|
|||||||
chd_avhuff_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy);
|
chd_avhuff_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy);
|
||||||
|
|
||||||
// core functionality
|
// core functionality
|
||||||
|
virtual void process(const uint8_t *src, uint32_t complen) override;
|
||||||
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) override;
|
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) override;
|
||||||
virtual void configure(int param, void *config) override;
|
virtual void configure(int param, void *config) override;
|
||||||
|
|
||||||
@ -575,9 +574,9 @@ const codec_entry *find_in_list(chd_codec_type type) noexcept
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
chd_codec::chd_codec(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_codec::chd_codec(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: m_chd(chd),
|
: m_chd(chd)
|
||||||
m_hunkbytes(hunkbytes),
|
, m_hunkbytes(hunkbytes)
|
||||||
m_lossy(lossy)
|
, m_lossy(lossy)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,10 +606,6 @@ void chd_codec::configure(int param, void *config)
|
|||||||
// CHD COMPRESSOR
|
// CHD COMPRESSOR
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// chd_compressor - constructor
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
chd_compressor::chd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_compressor::chd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_codec(chd, hunkbytes, lossy)
|
: chd_codec(chd, hunkbytes, lossy)
|
||||||
{
|
{
|
||||||
@ -622,15 +617,16 @@ chd_compressor::chd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
|||||||
// CHD DECOMPRESSOR
|
// CHD DECOMPRESSOR
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// chd_decompressor - constructor
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
chd_decompressor::chd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_decompressor::chd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_codec(chd, hunkbytes, lossy)
|
: chd_codec(chd, hunkbytes, lossy)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void chd_decompressor::process(const uint8_t *src, uint32_t complen)
|
||||||
|
{
|
||||||
|
throw std::error_condition(chd_file::error::UNSUPPORTED_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -1588,8 +1584,8 @@ void chd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, uin
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_compressor(chd, hunkbytes, lossy),
|
: chd_compressor(chd, hunkbytes, lossy)
|
||||||
m_buffer(hunkbytes)
|
, m_buffer(hunkbytes)
|
||||||
{
|
{
|
||||||
// make sure the CHD's hunk size is an even multiple of the frame size
|
// make sure the CHD's hunk size is an even multiple of the frame size
|
||||||
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
||||||
@ -1717,8 +1713,8 @@ uint32_t chd_cd_flac_compressor::blocksize(uint32_t bytes)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
|
||||||
: chd_decompressor(chd, hunkbytes, lossy),
|
: chd_decompressor(chd, hunkbytes, lossy)
|
||||||
m_buffer(hunkbytes)
|
, m_buffer(hunkbytes)
|
||||||
{
|
{
|
||||||
// make sure the CHD's hunk size is an even multiple of the frame size
|
// make sure the CHD's hunk size is an even multiple of the frame size
|
||||||
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
if (hunkbytes % cdrom_file::FRAME_SIZE != 0)
|
||||||
@ -1943,21 +1939,13 @@ chd_avhuff_decompressor::chd_avhuff_decompressor(chd_file &chd, uint32_t hunkbyt
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void chd_avhuff_decompressor::process(const uint8_t *src, uint32_t complen)
|
||||||
* @fn void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
|
{
|
||||||
*
|
// decode the audio and video
|
||||||
* @brief -------------------------------------------------
|
avhuff_error averr = m_decoder.decode_data(src, complen, nullptr);
|
||||||
* decompress - decompress data using the A/V codec
|
if (averr != AVHERR_NONE)
|
||||||
* -------------------------------------------------.
|
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
|
||||||
*
|
}
|
||||||
* @exception CHDERR_DECOMPRESSION_ERROR Thrown when a chderr decompression error error
|
|
||||||
* condition occurs.
|
|
||||||
*
|
|
||||||
* @param src Source for the.
|
|
||||||
* @param complen The complen.
|
|
||||||
* @param [in,out] dest If non-null, destination for the.
|
|
||||||
* @param destlen The destlen.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
|
void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
|
||||||
{
|
{
|
||||||
@ -1967,12 +1955,9 @@ void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, u
|
|||||||
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
|
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
|
||||||
|
|
||||||
// pad short frames with 0
|
// pad short frames with 0
|
||||||
if (dest != nullptr)
|
auto const size = avhuff_encoder::raw_data_size(dest);
|
||||||
{
|
if (size < destlen)
|
||||||
int size = avhuff_encoder::raw_data_size(dest);
|
memset(dest + size, 0, destlen - size);
|
||||||
if (size < destlen)
|
|
||||||
memset(dest + size, 0, destlen - size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
// copyright-holders:Aaron Giles
|
// copyright-holders:Aaron Giles
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
chdcodec.h
|
|
||||||
|
|
||||||
Codecs used by the CHD format
|
Codecs used by the CHD format
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -89,6 +87,7 @@ public:
|
|||||||
using ptr = std::unique_ptr<chd_decompressor>;
|
using ptr = std::unique_ptr<chd_decompressor>;
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
|
virtual void process(const uint8_t *src, uint32_t complen);
|
||||||
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) = 0;
|
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,9 +39,12 @@ public:
|
|||||||
: driver_device(mconfig, type, tag)
|
: driver_device(mconfig, type, tag)
|
||||||
, m_screen(*this, "screen")
|
, m_screen(*this, "screen")
|
||||||
, m_last_controls(0)
|
, m_last_controls(0)
|
||||||
, m_playing(false) { }
|
, m_playing(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ldplayer_ntsc(machine_config &config);
|
template <typename D, typename F>
|
||||||
|
void ldplayer_ntsc(machine_config &config, D &&player, F &&finder);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// device overrides
|
// device overrides
|
||||||
@ -107,14 +110,17 @@ class pr8210_state : public ldplayer_state
|
|||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
pr8210_state(const machine_config &mconfig, device_type type, const char *tag)
|
pr8210_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: ldplayer_state(mconfig, type, tag),
|
: ldplayer_state(mconfig, type, tag)
|
||||||
m_laserdisc(*this, "laserdisc"),
|
, m_laserdisc(*this, "laserdisc")
|
||||||
m_command_buffer_in(0),
|
, m_command_buffer_in(0)
|
||||||
m_command_buffer_out(0) { }
|
, m_command_buffer_out(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void pr8210(machine_config &config);
|
||||||
|
|
||||||
void pr8210(machine_config &config);
|
|
||||||
protected:
|
protected:
|
||||||
// device overrides
|
// driver_device implementation
|
||||||
virtual void machine_start() override ATTR_COLD;
|
virtual void machine_start() override ATTR_COLD;
|
||||||
virtual void machine_reset() override ATTR_COLD;
|
virtual void machine_reset() override ATTR_COLD;
|
||||||
|
|
||||||
@ -122,7 +128,7 @@ protected:
|
|||||||
virtual void execute_command(int command) override;
|
virtual void execute_command(int command) override;
|
||||||
|
|
||||||
// internal helpers
|
// internal helpers
|
||||||
inline void add_command(uint8_t command);
|
void add_command(uint8_t command);
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
TIMER_CALLBACK_MEMBER(bit_on);
|
TIMER_CALLBACK_MEMBER(bit_on);
|
||||||
@ -144,10 +150,13 @@ class ldv1000_state : public ldplayer_state
|
|||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
ldv1000_state(const machine_config &mconfig, device_type type, const char *tag)
|
ldv1000_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: ldplayer_state(mconfig, type, tag),
|
: ldplayer_state(mconfig, type, tag)
|
||||||
m_laserdisc(*this, "laserdisc") { }
|
, m_laserdisc(*this, "laserdisc")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ldv1000(machine_config &config);
|
||||||
|
|
||||||
void ldv1000(machine_config &config);
|
|
||||||
protected:
|
protected:
|
||||||
required_device<pioneer_ldv1000_device> m_laserdisc;
|
required_device<pioneer_ldv1000_device> m_laserdisc;
|
||||||
|
|
||||||
@ -341,7 +350,7 @@ void ldplayer_state::machine_reset()
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
void pr8210_state::add_command(uint8_t command)
|
inline void pr8210_state::add_command(uint8_t command)
|
||||||
{
|
{
|
||||||
m_command_buffer[m_command_buffer_in++ % std::size(m_command_buffer)] = (command & 0x1f) | 0x20;
|
m_command_buffer[m_command_buffer_in++ % std::size(m_command_buffer)] = (command & 0x1f) | 0x20;
|
||||||
m_command_buffer[m_command_buffer_in++ % std::size(m_command_buffer)] = 0x00 | 0x20;
|
m_command_buffer[m_command_buffer_in++ % std::size(m_command_buffer)] = 0x00 | 0x20;
|
||||||
@ -614,36 +623,34 @@ INPUT_PORTS_END
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
void ldplayer_state::ldplayer_ntsc(machine_config &config)
|
template <typename D, typename F>
|
||||||
|
void ldplayer_state::ldplayer_ntsc(machine_config &config, D &&player, F &&finder)
|
||||||
{
|
{
|
||||||
|
player(config, finder);
|
||||||
|
finder->set_get_disc(FUNC(ldplayer_state::get_disc));
|
||||||
|
finder->add_ntsc_screen(config, "screen");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ldv1000_state::ldv1000(machine_config &config)
|
void ldv1000_state::ldv1000(machine_config &config)
|
||||||
{
|
{
|
||||||
ldplayer_ntsc(config);
|
ldplayer_ntsc(config, PIONEER_LDV1000, m_laserdisc);
|
||||||
pioneer_ldv1000_device &laserdisc(PIONEER_LDV1000(config, "laserdisc"));
|
|
||||||
laserdisc.set_get_disc(FUNC(ldv1000_state::get_disc));
|
|
||||||
laserdisc.add_ntsc_screen(config, "screen");
|
|
||||||
|
|
||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
laserdisc.add_route(0, "lspeaker", 1.0);
|
m_laserdisc->add_route(0, "lspeaker", 1.0);
|
||||||
laserdisc.add_route(1, "rspeaker", 1.0);
|
m_laserdisc->add_route(1, "rspeaker", 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pr8210_state::pr8210(machine_config &config)
|
void pr8210_state::pr8210(machine_config &config)
|
||||||
{
|
{
|
||||||
ldplayer_ntsc(config);
|
ldplayer_ntsc(config, PIONEER_PR8210, m_laserdisc);
|
||||||
pioneer_pr8210_device &laserdisc(PIONEER_PR8210(config, "laserdisc"));
|
|
||||||
laserdisc.set_get_disc(FUNC(pr8210_state::get_disc));
|
|
||||||
laserdisc.add_ntsc_screen(config, "screen");
|
|
||||||
|
|
||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
laserdisc.add_route(0, "lspeaker", 1.0);
|
m_laserdisc->add_route(0, "lspeaker", 1.0);
|
||||||
laserdisc.add_route(1, "rspeaker", 1.0);
|
m_laserdisc->add_route(1, "rspeaker", 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3082,7 +3082,7 @@ static void do_extract_ld(parameters_map ¶ms)
|
|||||||
input_chd.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
input_chd.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
||||||
|
|
||||||
// read the hunk into the buffers
|
// read the hunk into the buffers
|
||||||
std::error_condition err = input_chd.read_hunk(framenum, nullptr);
|
std::error_condition err = input_chd.codec_process_hunk(framenum);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
uint64_t filepos = ~uint64_t(0);
|
uint64_t filepos = ~uint64_t(0);
|
||||||
|
@ -249,7 +249,7 @@ static bool read_chd(chd_file &file, uint32_t field, movie_info &info, uint32_t
|
|||||||
file.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
file.codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
||||||
|
|
||||||
// read the field
|
// read the field
|
||||||
std::error_condition chderr = file.read_hunk(field, nullptr);
|
std::error_condition chderr = file.codec_process_hunk(field);
|
||||||
return !chderr;
|
return !chderr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ static int read_chd(void *file, int frame, bitmap_yuy16 &bitmap, int16_t *lsound
|
|||||||
chdfile->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
chdfile->codec_configure(CHD_CODEC_AVHUFF, AVHUFF_CODEC_DECOMPRESS_CONFIG, &avconfig);
|
||||||
|
|
||||||
// read the frame
|
// read the frame
|
||||||
std::error_condition chderr = chdfile->read_hunk(frame * interlace_factor + fieldnum, nullptr);
|
std::error_condition chderr = chdfile->codec_process_hunk(frame * interlace_factor + fieldnum);
|
||||||
if (chderr)
|
if (chderr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user