Bring cdriso.c up to date to enable CCDDA
This commit is contained in:
parent
d880179b2a
commit
8f19dd4bc9
|
@ -7,3 +7,4 @@ macosx/build
|
||||||
xcuserdata
|
xcuserdata
|
||||||
macosx/Info.plistvers.plist
|
macosx/Info.plistvers.plist
|
||||||
*.kdev4
|
*.kdev4
|
||||||
|
linux_build.sh
|
||||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -26,6 +26,7 @@ PCSX-Reloaded Authors/Contributors: avlex (Help on xcode project)
|
||||||
edgbla (Root counters, SIO1, various core/plugin fixes)
|
edgbla (Root counters, SIO1, various core/plugin fixes)
|
||||||
Firnis (GTE code from PCSX-Revolution Project)
|
Firnis (GTE code from PCSX-Revolution Project)
|
||||||
Hopkat (Sound plugin improvements, core fixes)
|
Hopkat (Sound plugin improvements, core fixes)
|
||||||
|
iSage (compressed CD-DA, migration to CMake)
|
||||||
Gabriele Gorla (MDEC decoder)
|
Gabriele Gorla (MDEC decoder)
|
||||||
MaddTheSane (Various bugfixes)
|
MaddTheSane (Various bugfixes)
|
||||||
maggix (Snow Leopard compile fix)
|
maggix (Snow Leopard compile fix)
|
||||||
|
|
|
@ -177,6 +177,7 @@ if test "$BUILD_CCDDA" = "yes"; then
|
||||||
AC_CHECK_LIB([avcodec], [main], [LIBS="$LIBS -lavcodec"], AC_MSG_ERROR("No avcodec library"))
|
AC_CHECK_LIB([avcodec], [main], [LIBS="$LIBS -lavcodec"], AC_MSG_ERROR("No avcodec library"))
|
||||||
AC_CHECK_LIB([avutil], [main], [LIBS="$LIBS -lavutil"], AC_MSG_ERROR("No avutil library"))
|
AC_CHECK_LIB([avutil], [main], [LIBS="$LIBS -lavutil"], AC_MSG_ERROR("No avutil library"))
|
||||||
AC_CHECK_LIB([avformat], [main], [LIBS="$LIBS -lavformat"], AC_MSG_ERROR("No avformat library"))
|
AC_CHECK_LIB([avformat], [main], [LIBS="$LIBS -lavformat"], AC_MSG_ERROR("No avformat library"))
|
||||||
|
AC_CHECK_LIB([swresample], [main], [LIBS="$LIBS -lswresample"], AC_MSG_ERROR("No swresample library"))
|
||||||
#AC_CHECK_LIB(avcodec ,[main],AC_DEFINE([HAVE_LIBAVCODEC], [1], [ ]),AC_MSG_ERROR([$errormsgl]))
|
#AC_CHECK_LIB(avcodec ,[main],AC_DEFINE([HAVE_LIBAVCODEC], [1], [ ]),AC_MSG_ERROR([$errormsgl]))
|
||||||
#AC_CHECK_LIB(swscale ,[main],AC_DEFINE([HAVE_LIBSWSCALE], [1], [ ]),AC_MSG_ERROR([$errormsgl]), [-lavutil])
|
#AC_CHECK_LIB(swscale ,[main],AC_DEFINE([HAVE_LIBSWSCALE], [1], [ ]),AC_MSG_ERROR([$errormsgl]), [-lavutil])
|
||||||
#AC_CHECK_LIB(avdevice ,[main],AC_DEFINE([HAVE_LIBAVDEVICE], [1], [ ]),AC_MSG_ERROR([$errormsgl]), [-lavcodec -lavutil -lavformat])
|
#AC_CHECK_LIB(avdevice ,[main],AC_DEFINE([HAVE_LIBAVDEVICE], [1], [ ]),AC_MSG_ERROR([$errormsgl]), [-lavcodec -lavutil -lavformat])
|
||||||
|
|
|
@ -4,25 +4,25 @@ AM_CPPFLAGS = -DLOCALE_DIR=\"${datadir}/locale/\" \
|
||||||
noinst_LIBRARIES = libpcsxcore.a
|
noinst_LIBRARIES = libpcsxcore.a
|
||||||
|
|
||||||
libpcsxcore_a_SOURCES = \
|
libpcsxcore_a_SOURCES = \
|
||||||
psxbios.c \
|
psxbios.c \
|
||||||
cdrom.c \
|
cdrom.c \
|
||||||
psxcounters.c \
|
psxcounters.c \
|
||||||
psxdma.c \
|
psxdma.c \
|
||||||
disr3000a.c \
|
disr3000a.c \
|
||||||
gpu.c \
|
gpu.c \
|
||||||
gpu.h \
|
gpu.h \
|
||||||
spu.c \
|
spu.c \
|
||||||
sio.c \
|
sio.c \
|
||||||
psxhw.c \
|
psxhw.c \
|
||||||
mdec.c \
|
mdec.c \
|
||||||
psxmem.c \
|
psxmem.c \
|
||||||
misc.c \
|
misc.c \
|
||||||
plugins.c \
|
plugins.c \
|
||||||
decode_xa.c \
|
decode_xa.c \
|
||||||
r3000a.c \
|
r3000a.c \
|
||||||
psxinterpreter.c \
|
psxinterpreter.c \
|
||||||
gte.c \
|
gte.c \
|
||||||
psxhle.c \
|
psxhle.c \
|
||||||
cdrom.h \
|
cdrom.h \
|
||||||
coff.h \
|
coff.h \
|
||||||
debug.c \
|
debug.c \
|
||||||
|
@ -68,35 +68,35 @@ libpcsxcore_a_SOURCES = \
|
||||||
|
|
||||||
if ARCH_X86_64
|
if ARCH_X86_64
|
||||||
libpcsxcore_a_SOURCES += \
|
libpcsxcore_a_SOURCES += \
|
||||||
ix86_64/iGte.h \
|
ix86_64/iGte.h \
|
||||||
ix86_64/iR3000A-64.c \
|
ix86_64/iR3000A-64.c \
|
||||||
ix86_64/ix86-64.c \
|
ix86_64/ix86-64.c \
|
||||||
ix86_64/ix86-64.h \
|
ix86_64/ix86-64.h \
|
||||||
ix86_64/ix86_cpudetect.c \
|
ix86_64/ix86_cpudetect.c \
|
||||||
ix86_64/ix86_fpu.c \
|
ix86_64/ix86_fpu.c \
|
||||||
ix86_64/ix86_3dnow.c \
|
ix86_64/ix86_3dnow.c \
|
||||||
ix86_64/ix86_mmx.c \
|
ix86_64/ix86_mmx.c \
|
||||||
ix86_64/ix86_sse.c \
|
ix86_64/ix86_sse.c \
|
||||||
ix86_64/iPGXP.h
|
ix86_64/iPGXP.h
|
||||||
else
|
else
|
||||||
if ARCH_X86
|
if ARCH_X86
|
||||||
libpcsxcore_a_SOURCES += \
|
libpcsxcore_a_SOURCES += \
|
||||||
ix86/iGte.h \
|
ix86/iGte.h \
|
||||||
ix86/iR3000A.c \
|
ix86/iR3000A.c \
|
||||||
ix86/ix86.c \
|
ix86/ix86.c \
|
||||||
ix86/ix86.h \
|
ix86/ix86.h \
|
||||||
ix86/iPGXP.h
|
ix86/iPGXP.h
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ARCH_PPC
|
if ARCH_PPC
|
||||||
libpcsxcore_a_SOURCES += \
|
libpcsxcore_a_SOURCES += \
|
||||||
ppc/pGte.h \
|
ppc/pGte.h \
|
||||||
ppc/pR3000A.c \
|
ppc/pR3000A.c \
|
||||||
ppc/ppc.c \
|
ppc/ppc.c \
|
||||||
ppc/ppc.h \
|
ppc/ppc.h \
|
||||||
ppc/ppc_mnemonics.h \
|
ppc/ppc_mnemonics.h \
|
||||||
ppc/reguse.c \
|
ppc/reguse.c \
|
||||||
ppc/reguse.h
|
ppc/reguse.h
|
||||||
libpcsxcore_a_CCASFLAGS = -x assembler-with-cpp -mregnames -D__POWERPC__
|
libpcsxcore_a_CCASFLAGS = -x assembler-with-cpp -mregnames -D__POWERPC__
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -40,14 +40,11 @@
|
||||||
#ifdef ENABLE_CCDDA
|
#ifdef ENABLE_CCDDA
|
||||||
#include "libavcodec/avcodec.h"
|
#include "libavcodec/avcodec.h"
|
||||||
#include "libavutil/mathematics.h"
|
#include "libavutil/mathematics.h"
|
||||||
|
#include <libavutil/opt.h>
|
||||||
|
#include <libavutil/timestamp.h>
|
||||||
#include "libavformat/avformat.h"
|
#include "libavformat/avformat.h"
|
||||||
|
#include <libswresample/swresample.h>
|
||||||
|
|
||||||
#define INBUF_SIZE 4096
|
|
||||||
#define AUDIO_INBUF_SIZE INBUF_SIZE*4
|
|
||||||
#define AUDIO_REFILL_THRESH 4096
|
|
||||||
/*#ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
|
|
||||||
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
|
|
||||||
#endif*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int cdrIsoMultidiskCount;
|
unsigned int cdrIsoMultidiskCount;
|
||||||
|
@ -88,8 +85,6 @@ static struct {
|
||||||
} *compr_img;
|
} *compr_img;
|
||||||
|
|
||||||
int (*cdimg_read_func)(FILE *f, unsigned int base, void *dest, int sector);
|
int (*cdimg_read_func)(FILE *f, unsigned int base, void *dest, int sector);
|
||||||
static int cdread_normal(FILE *f, unsigned int base, void *dest, int sector);
|
|
||||||
static int cdread_ecm_decode(FILE *f, unsigned int base, void *dest, int sector);
|
|
||||||
|
|
||||||
char* CALLBACK CDR__getDriveLetter(void);
|
char* CALLBACK CDR__getDriveLetter(void);
|
||||||
long CALLBACK CDR__configure(void);
|
long CALLBACK CDR__configure(void);
|
||||||
|
@ -106,9 +101,6 @@ struct trackinfo {
|
||||||
u8 length[3]; // MSF-format
|
u8 length[3]; // MSF-format
|
||||||
FILE *handle; // for multi-track images CDDA
|
FILE *handle; // for multi-track images CDDA
|
||||||
enum {NONE=0, BIN=1, CCDDA=2
|
enum {NONE=0, BIN=1, CCDDA=2
|
||||||
#ifdef ENABLE_CCDDA1
|
|
||||||
,MP3=AV_CODEC_ID_MP3, APE=AV_CODEC_ID_APE, FLAC=AV_CODEC_ID_FLAC
|
|
||||||
#endif
|
|
||||||
} cddatype; // BIN, WAV, MP3, APE
|
} cddatype; // BIN, WAV, MP3, APE
|
||||||
void* decoded_buffer;
|
void* decoded_buffer;
|
||||||
u32 len_decoded_buffer;
|
u32 len_decoded_buffer;
|
||||||
|
@ -169,17 +161,6 @@ static int get_cdda_type(const char *str)
|
||||||
if (strncmp((str+lenstr-3), "bin", 3) == 0) {
|
if (strncmp((str+lenstr-3), "bin", 3) == 0) {
|
||||||
return BIN;
|
return BIN;
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_CCDDA1
|
|
||||||
else if (strncmp((str+lenstr-3), "mp3", 3) == 0) {
|
|
||||||
return MP3;
|
|
||||||
}
|
|
||||||
else if (strncmp((str+lenstr-3), "ape", 3) == 0) {
|
|
||||||
return APE;
|
|
||||||
}
|
|
||||||
else if (strncmp((str+lenstr-4), "flac", 4) == 0) {
|
|
||||||
return FLAC;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_CCDDA
|
#ifdef ENABLE_CCDDA
|
||||||
else {
|
else {
|
||||||
return CCDDA;
|
return CCDDA;
|
||||||
|
@ -196,16 +177,17 @@ static int get_cdda_type(const char *str)
|
||||||
return BIN; // no valid extension or no support; assume bin
|
return BIN; // no valid extension or no support; assume bin
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_compressed_cdda_track_length(const char* filepath) {
|
int get_compressed_cdda_track_length(const char* filepath) {
|
||||||
int seconds = -1;
|
int seconds = -1;
|
||||||
#ifdef ENABLE_CCDDA
|
#ifdef ENABLE_CCDDA
|
||||||
|
av_log_set_level(AV_LOG_QUIET);
|
||||||
av_register_all();
|
av_register_all();
|
||||||
|
|
||||||
AVFormatContext * inAudioFormat = NULL;
|
AVFormatContext * inAudioFormat = NULL;
|
||||||
inAudioFormat = avformat_alloc_context();
|
inAudioFormat = avformat_alloc_context();
|
||||||
int errorCode = avformat_open_input(&inAudioFormat, filepath, NULL, NULL);
|
int errorCode = avformat_open_input(&inAudioFormat, filepath, NULL, NULL);
|
||||||
avformat_find_stream_info(inAudioFormat, NULL);
|
avformat_find_stream_info(inAudioFormat, NULL);
|
||||||
seconds = (int)(inAudioFormat->duration/AV_TIME_BASE);
|
seconds = (int)ceil((double)inAudioFormat->duration/(double)AV_TIME_BASE);
|
||||||
avformat_close_input(&inAudioFormat);
|
avformat_close_input(&inAudioFormat);
|
||||||
#endif
|
#endif
|
||||||
return seconds;
|
return seconds;
|
||||||
|
@ -213,132 +195,208 @@ static int get_compressed_cdda_track_length(const char* filepath) {
|
||||||
|
|
||||||
|
|
||||||
#ifdef ENABLE_CCDDA
|
#ifdef ENABLE_CCDDA
|
||||||
static int decode_compressed_cdda_track(FILE* outfile, const char* infilepath, s32 id) {
|
|
||||||
AVCodec *codec;
|
|
||||||
AVCodecContext *c=NULL;
|
|
||||||
AVFormatContext *inAudioFormat = NULL;
|
|
||||||
s32 len;
|
|
||||||
AVPacket avpkt;
|
|
||||||
AVFrame *decoded_frame = NULL;
|
|
||||||
s32 got_frame = 0, moreFrames = 1;
|
|
||||||
s32 audio_stream_index;
|
|
||||||
s32 ret;
|
|
||||||
|
|
||||||
//av_init_packet(&avpkt);
|
int decode_packet(int *got_frame, AVPacket pkt, int audio_stream_idx, AVFrame* frame, AVCodecContext* audio_dec_ctx, void* buf, int* size, SwrContext* swr) {
|
||||||
|
int ret = 0;
|
||||||
avcodec_register_all();
|
int decoded = pkt.size;
|
||||||
|
*got_frame = 0;
|
||||||
inAudioFormat = avformat_alloc_context();
|
|
||||||
int errorCode = avformat_open_input(&inAudioFormat, infilepath, NULL, NULL);
|
if (pkt.stream_index == audio_stream_idx) {
|
||||||
if (errorCode) {
|
ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
|
||||||
SysMessage(_("Audio file opening failed!\n"));
|
if (ret < 0) {
|
||||||
return errorCode;
|
SysPrintf(_("Error decoding audio frame\n"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some audio decoders decode only part of the packet, and have to be
|
||||||
|
* called again with the remainder of the packet data.
|
||||||
|
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
|
||||||
|
* Also, some decoders might over-read the packet. */
|
||||||
|
|
||||||
|
decoded = FFMIN(ret, pkt.size);
|
||||||
|
|
||||||
|
if (*got_frame) {
|
||||||
|
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||||
|
swr_convert(swr, (uint8_t**)&buf, frame->nb_samples, (const uint8_t **)frame->data, frame->nb_samples);
|
||||||
|
(*size)+=(unpadded_linesize*2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
avformat_find_stream_info(inAudioFormat, NULL);
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type) {
|
||||||
|
int ret, stream_index;
|
||||||
|
AVStream *st;
|
||||||
|
AVCodecContext *dec_ctx = NULL;
|
||||||
|
AVCodec *dec = NULL;
|
||||||
|
AVDictionary *opts = NULL;
|
||||||
|
|
||||||
|
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||||
|
|
||||||
/* select the audio stream */
|
|
||||||
ret = av_find_best_stream(inAudioFormat, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
avformat_close_input(&inAudioFormat);
|
SysPrintf(_("Could not find %s stream in input file\n"),
|
||||||
SysMessage(_("Couldn't find any audio stream in file\n"));
|
av_get_media_type_string(type));
|
||||||
return ret;
|
return ret;
|
||||||
|
} else {
|
||||||
|
stream_index = ret;
|
||||||
|
st = fmt_ctx->streams[stream_index];
|
||||||
|
|
||||||
|
dec_ctx = st->codec;
|
||||||
|
dec = avcodec_find_decoder(dec_ctx->codec_id);
|
||||||
|
if (!dec) {
|
||||||
|
SysPrintf(_("Failed to find %s codec\n"),
|
||||||
|
av_get_media_type_string(type));
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
/* Init the decoders, with or without reference counting */
|
||||||
|
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||||
|
SysPrintf(_("Failed to open %s codec\n"),
|
||||||
|
av_get_media_type_string(type));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
*stream_idx = stream_index;
|
||||||
}
|
}
|
||||||
audio_stream_index = ret;
|
|
||||||
c = inAudioFormat->streams[audio_stream_index]->codec;
|
|
||||||
av_opt_set_int(c, "refcounted_frames", 1, 0);
|
|
||||||
|
|
||||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
|
||||||
c->channels = 2;
|
|
||||||
c->sample_rate = 44100;
|
|
||||||
|
|
||||||
/* open it */
|
|
||||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
|
||||||
SysMessage(_("Audio decoder opening failed. Compressed audio support not available.\n"));
|
|
||||||
avformat_close_input(&inAudioFormat);
|
|
||||||
return 3; // codec open failed
|
|
||||||
}
|
|
||||||
//http://ffmpeg.org/doxygen/trunk/doc_2examples_2filtering_audio_8c-example.html#a80
|
|
||||||
//http://blog.tomaka17.com/2012/03/libavcodeclibavformat-tutorial/
|
|
||||||
do {
|
|
||||||
if ((moreFrames=av_read_frame(inAudioFormat, &avpkt)) < 0) {// returns non-zero on error
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (avpkt.stream_index != audio_stream_index) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decoded_frame) {
|
|
||||||
if (!(decoded_frame = avcodec_alloc_frame())) {
|
|
||||||
SysMessage(_(" -> Error allocating audio frame buffer. This track will not be available."));
|
|
||||||
avformat_close_input(&inAudioFormat);
|
|
||||||
av_free(&decoded_frame);
|
|
||||||
return 1; // error decoding frame
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
avcodec_get_frame_defaults(decoded_frame);
|
|
||||||
}
|
|
||||||
len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
|
|
||||||
if (len > 0 && got_frame) {
|
|
||||||
/* if a frame has been decoded, output it */
|
|
||||||
int data_size = av_samples_get_buffer_size(NULL, c->channels,
|
|
||||||
decoded_frame->nb_samples,
|
|
||||||
c->sample_fmt, 1);
|
|
||||||
//printf ("Channels %i/%i: %i -> %i/%i\n", len, data_size, decoded_frame->sample_rate, c->channels, c->sample_rate);
|
|
||||||
fwrite(decoded_frame->data[0], 1, data_size, outfile);
|
|
||||||
}
|
|
||||||
av_free_packet(&avpkt);
|
|
||||||
//avcodec_free_frame(&decoded_frame);
|
|
||||||
} while (moreFrames >= 0); // TODO: check for possible leaks
|
|
||||||
|
|
||||||
// file will be closed later on, now just flush it
|
|
||||||
fflush(outfile);
|
|
||||||
|
|
||||||
avformat_close_input(&inAudioFormat);
|
|
||||||
|
|
||||||
// TODO not sure if all resources are freed...
|
|
||||||
//avcodec_close(c);
|
|
||||||
//av_free(c);
|
|
||||||
//av_free(&decoded_frame);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int decode_compressed_cdda_track(char* buf, char* src_filename, int* size) {
|
||||||
|
AVFormatContext *fmt_ctx = NULL;
|
||||||
|
AVCodecContext *audio_dec_ctx;
|
||||||
|
AVStream *audio_stream = NULL;
|
||||||
|
int audio_stream_idx = -1;
|
||||||
|
AVFrame *frame = NULL;
|
||||||
|
AVPacket pkt;
|
||||||
|
SwrContext *resample_context;
|
||||||
|
int ret = 0, got_frame;
|
||||||
|
|
||||||
|
av_register_all();
|
||||||
|
|
||||||
|
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||||
|
SysPrintf(_("Could not open source file %s\n"), src_filename);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
|
||||||
|
SysPrintf(_("Could not find stream information\n"));
|
||||||
|
ret = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||||
|
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
||||||
|
audio_dec_ctx = audio_stream->codec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!audio_stream) {
|
||||||
|
SysPrintf(_("Could not find audio stream in the input, aborting\n"));
|
||||||
|
ret = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init and configure resampler
|
||||||
|
resample_context = swr_alloc();
|
||||||
|
if (!resample_context)
|
||||||
|
{
|
||||||
|
SysPrintf(_("Could not allocate resample context"));
|
||||||
|
ret = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
av_opt_set_int(resample_context, "in_channel_layout", audio_dec_ctx->channel_layout, 0);
|
||||||
|
av_opt_set_int(resample_context, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||||
|
av_opt_set_int(resample_context, "in_sample_rate", audio_dec_ctx->sample_rate, 0);
|
||||||
|
av_opt_set_int(resample_context, "out_sample_rate", 44100, 0);
|
||||||
|
av_opt_set_sample_fmt(resample_context, "in_sample_fmt", audio_dec_ctx->sample_fmt, 0);
|
||||||
|
av_opt_set_sample_fmt(resample_context, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||||
|
if (swr_init(resample_context) < 0)
|
||||||
|
{
|
||||||
|
SysPrintf(_("Could not open resample context"));
|
||||||
|
ret = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
frame = av_frame_alloc();
|
||||||
|
if (!frame) {
|
||||||
|
SysPrintf(_("Could not allocate frame\n"));
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize packet, set data to NULL, let the demuxer fill it */
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
pkt.data = NULL;
|
||||||
|
pkt.size = 0;
|
||||||
|
|
||||||
|
/* read frames from the file */
|
||||||
|
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
|
||||||
|
AVPacket orig_pkt = pkt;
|
||||||
|
do {
|
||||||
|
ret = decode_packet(&got_frame, pkt, audio_stream_idx, frame, audio_dec_ctx, buf+(*size), size, resample_context);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
pkt.data += ret;
|
||||||
|
pkt.size -= ret;
|
||||||
|
} while (pkt.size > 0);
|
||||||
|
av_packet_unref(&orig_pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flush cached frames */
|
||||||
|
pkt.data = NULL;
|
||||||
|
pkt.size = 0;
|
||||||
|
do {
|
||||||
|
decode_packet(&got_frame, pkt, audio_stream_idx, frame, audio_dec_ctx, buf+(*size), size, resample_context);
|
||||||
|
} while (got_frame);
|
||||||
|
|
||||||
|
end:
|
||||||
|
swr_free(&resample_context);
|
||||||
|
avcodec_close(audio_dec_ctx);
|
||||||
|
avformat_close_input(&fmt_ctx);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
return ret < 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int do_decode_cdda(struct trackinfo* tri, u32 tracknumber) {
|
int do_decode_cdda(struct trackinfo* tri, u32 tracknumber) {
|
||||||
#ifndef ENABLE_CCDDA
|
#ifndef ENABLE_CCDDA
|
||||||
return 4; // support is not compiled in
|
return 0; // support is not compiled in
|
||||||
#else
|
#else
|
||||||
tri->decoded_buffer = malloc(tri->len_decoded_buffer);
|
tri->decoded_buffer = malloc(tri->len_decoded_buffer);
|
||||||
FILE* decoded_cdda = fmemopen(tri->decoded_buffer, tri->len_decoded_buffer, "wb");
|
memset(tri->decoded_buffer,0,tri->len_decoded_buffer-1);
|
||||||
|
|
||||||
if (decoded_cdda == NULL || tri->decoded_buffer == NULL) {
|
if (tri->decoded_buffer == NULL) {
|
||||||
SysMessage(_("Could not allocate memory to decode CDDA TRACK: %s\n"), tri->filepath);
|
SysMessage(_("Could not allocate memory to decode CDDA TRACK: %s\n"), tri->filepath);
|
||||||
|
fclose(tri->handle); // encoded file handle not needed anymore
|
||||||
|
tri->handle = fmemopen(NULL, 1, "rb"); // change handle to decoded one
|
||||||
|
tri->cddatype = BIN;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(tri->handle); // encoded file handle not needed anymore
|
fclose(tri->handle); // encoded file handle not needed anymore
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
SysPrintf(_("Decoding audio tr#%u (%s)..."), tracknumber, tri->filepath);
|
SysPrintf(_("Decoding audio tr#%u (%s)..."), tracknumber, tri->filepath);
|
||||||
// decode 2nd input param to 1st output param
|
|
||||||
if ((ret=decode_compressed_cdda_track(decoded_cdda, tri->filepath /*tri->handle*/, tri->cddatype)) == 0) {
|
int len=0;
|
||||||
int len1 = ftell(decoded_cdda);
|
|
||||||
if (len1 > tri->len_decoded_buffer) {
|
if ((ret=decode_compressed_cdda_track(tri->decoded_buffer, tri->filepath, &len)) == 0) {
|
||||||
|
if (len > tri->len_decoded_buffer) {
|
||||||
SysPrintf(_("Buffer overflow..."));
|
SysPrintf(_("Buffer overflow..."));
|
||||||
|
SysPrintf(_("Actual %i vs. %i estimated\n"), len, tri->len_decoded_buffer);
|
||||||
|
len = tri->len_decoded_buffer; // we probably segfaulted already, oh well...
|
||||||
}
|
}
|
||||||
//printf("actual %i vs. %i estimated", len1, tri->len_decoded_buffer);
|
|
||||||
fclose(decoded_cdda); // close wb file now and will be opened as rb
|
tri->handle = fmemopen(tri->decoded_buffer, len, "rb"); // change handle to decoded one
|
||||||
tri->handle = fmemopen(tri->decoded_buffer, len1, "rb"); // change handle to decoded one
|
|
||||||
SysPrintf(_("OK\n"), tri->filepath);
|
SysPrintf(_("OK\n"), tri->filepath);
|
||||||
}
|
}
|
||||||
tri->cddatype = BIN;
|
tri->cddatype = BIN;
|
||||||
return ret;
|
return len;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function tries to get the .toc file of the given .bin
|
// this function tries to get the .toc file of the given .bin
|
||||||
// the necessary data is put into the ti (trackinformation)-array
|
// the necessary data is put into the ti (trackinformation)-array
|
||||||
static int parsetoc(const char *isofile) {
|
static int parsetoc(const char *isofile) {
|
||||||
char tocname[MAXPATHLEN];
|
char tocname[MAXPATHLEN], filename[MAXPATHLEN], *ptr;
|
||||||
FILE *fi;
|
FILE *fi;
|
||||||
char linebuf[256], tmp[256], name[256];
|
char linebuf[256], tmp[256], name[256];
|
||||||
char *token;
|
char *token;
|
||||||
|
@ -377,6 +435,14 @@ static int parsetoc(const char *isofile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy(filename, tocname);
|
||||||
|
if ((ptr = strrchr(filename, '/')) == NULL)
|
||||||
|
ptr = strrchr(filename, '\\');
|
||||||
|
if (ptr == NULL)
|
||||||
|
*ptr = 0;
|
||||||
|
else
|
||||||
|
*(ptr + 1) = 0;
|
||||||
|
|
||||||
memset(&ti, 0, sizeof(ti));
|
memset(&ti, 0, sizeof(ti));
|
||||||
cddaBigEndian = TRUE; // cdrdao uses big-endian for CD Audio
|
cddaBigEndian = TRUE; // cdrdao uses big-endian for CD Audio
|
||||||
|
|
||||||
|
@ -427,6 +493,8 @@ static int parsetoc(const char *isofile) {
|
||||||
else {
|
else {
|
||||||
sscanf(linebuf, "DATAFILE \"%[^\"]\" %8s", name, time);
|
sscanf(linebuf, "DATAFILE \"%[^\"]\" %8s", name, time);
|
||||||
tok2msf((char *)&time, (char *)&ti[numtracks].length);
|
tok2msf((char *)&time, (char *)&ti[numtracks].length);
|
||||||
|
strcat(filename, name);
|
||||||
|
ti[numtracks].handle = fopen(filename, "rb");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcmp(token, "FILE")) {
|
else if (!strcmp(token, "FILE")) {
|
||||||
|
@ -466,6 +534,8 @@ static int parsetoc(const char *isofile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (numtracks > 0)
|
||||||
|
cdHandle = fopen(filename, "rb");
|
||||||
|
|
||||||
fclose(fi);
|
fclose(fi);
|
||||||
|
|
||||||
|
@ -473,160 +543,7 @@ static int parsetoc(const char *isofile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int(*cdimg_read_func_archive)(FILE *f, unsigned int base, void *dest, int sector) = NULL;
|
int handlearchive(const char *isoname, s32* accurate_length);
|
||||||
#ifdef HAVE_LIBARCHIVE
|
|
||||||
#include <archive.h>
|
|
||||||
#include <archive_entry.h>
|
|
||||||
|
|
||||||
struct archive *a = NULL;
|
|
||||||
u32 len_uncompressed_buffer = 0;
|
|
||||||
void *cdimage_buffer_mem = NULL;
|
|
||||||
FILE* cdimage_buffer = NULL; //cdHandle to store file
|
|
||||||
|
|
||||||
int aropen(FILE* fparchive, const char* _fn) {
|
|
||||||
s32 r;
|
|
||||||
u64 length = 0, length_peek;
|
|
||||||
boolean use_temp_file = FALSE; // TODO make a config param
|
|
||||||
static struct archive_entry *ae = NULL;
|
|
||||||
struct archive_entry *ae_peek;
|
|
||||||
|
|
||||||
if (a == NULL && cdimage_buffer == NULL) {
|
|
||||||
// We open file twice. First to peek sizes. This nastyness due used interface.
|
|
||||||
a = archive_read_new();
|
|
||||||
r = archive_read_support_compression_all(a);
|
|
||||||
r = archive_read_support_format_all(a);
|
|
||||||
//r = archive_read_support_filter_all(a);
|
|
||||||
//r = archive_read_support_format_raw(a);
|
|
||||||
//r = archive_read_open_FILE(a, archive);
|
|
||||||
archive_read_open_filename(a, _fn, 75 * CD_FRAMESIZE_RAW);
|
|
||||||
if (r != ARCHIVE_OK) {
|
|
||||||
SysPrintf("Archive open failed (%i).\n", r);
|
|
||||||
archive_read_free(a);
|
|
||||||
a = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// Get the biggest file in archive
|
|
||||||
while ((r = archive_read_next_header(a, &ae_peek)) == ARCHIVE_OK) {
|
|
||||||
length_peek = archive_entry_size(ae_peek);
|
|
||||||
//printf("Entry canditate %s %i\n", archive_entry_pathname(ae_peek), length_peek);
|
|
||||||
length = MAX(length_peek, length);
|
|
||||||
ae = (ae == NULL ? ae_peek : ae);
|
|
||||||
}
|
|
||||||
archive_read_free(a);
|
|
||||||
if (ae == NULL) {
|
|
||||||
SysPrintf("Archive entry read failed (%i).\n", r);
|
|
||||||
a = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
//Now really open the file
|
|
||||||
a = archive_read_new();
|
|
||||||
r = archive_read_support_compression_all(a);
|
|
||||||
r = archive_read_support_format_all(a);
|
|
||||||
archive_read_open_filename(a, _fn, 75 * CD_FRAMESIZE_RAW);
|
|
||||||
while ((r = archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
|
|
||||||
length_peek = archive_entry_size(ae);
|
|
||||||
if (length_peek == length) {
|
|
||||||
//ae = ae_peek;
|
|
||||||
SysPrintf(" -- Selected entry %s %i", archive_entry_pathname(ae), length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
len_uncompressed_buffer = length ? length : 700 * 1024 * 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_temp_file && (cdimage_buffer == NULL || cdHandle != cdimage_buffer)) {
|
|
||||||
cdimage_buffer = fopen("/tmp/pcsxr.tmp.bin", "w+b");
|
|
||||||
}
|
|
||||||
else if (!use_temp_file && (cdimage_buffer == NULL || cdHandle != cdimage_buffer)) {
|
|
||||||
if (cdimage_buffer_mem == NULL && ((cdimage_buffer_mem = malloc(len_uncompressed_buffer)) == NULL)) {
|
|
||||||
SysMessage("Could not reserve enough memory for full image buffer.\n");
|
|
||||||
exit(3);
|
|
||||||
}
|
|
||||||
//printf("Memory ok2 %u %p\n", len_uncompressed_buffer, cdimage_buffer_mem);
|
|
||||||
cdimage_buffer = fmemopen(cdimage_buffer_mem, len_uncompressed_buffer, "w+b");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cdHandle != cdimage_buffer) {
|
|
||||||
fclose(cdHandle); // opened thru archive so this not needed anymore
|
|
||||||
cdHandle = cdimage_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cdread_archive(FILE *f, unsigned int base, void *dest, int sector)
|
|
||||||
{
|
|
||||||
s32 r;
|
|
||||||
size_t size;
|
|
||||||
size_t readsize;
|
|
||||||
static off_t offset = 0; // w/o read always or static/ftell
|
|
||||||
const void *buff;
|
|
||||||
|
|
||||||
// If not pointing to archive file but CDDA file or some other track
|
|
||||||
if (f != cdHandle) {
|
|
||||||
return cdimg_read_func_archive(f, base, dest, sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jump if already completely read
|
|
||||||
if (a != NULL /*&& (ecm_file_detected || sector*CD_FRAMESIZE_RAW <= len_uncompressed_buffer)*/) {
|
|
||||||
readsize = (sector + 1) * CD_FRAMESIZE_RAW;
|
|
||||||
for (fseek(cdimage_buffer, offset, SEEK_SET); offset < readsize;) {
|
|
||||||
r = archive_read_data_block(a, &buff, &size, &offset);
|
|
||||||
offset += size;
|
|
||||||
SysPrintf("ReadArchive seek:%u(%u) cur:%u(%u)\r", sector, readsize / 1024, offset / CD_FRAMESIZE_RAW, offset / 1024);
|
|
||||||
fwrite(buff, size, 1, cdimage_buffer);
|
|
||||||
if (r != ARCHIVE_OK) {
|
|
||||||
//SysPrintf("End of archive.\n");
|
|
||||||
archive_read_free(a);
|
|
||||||
a = NULL;
|
|
||||||
readsize = offset;
|
|
||||||
fflush(cdimage_buffer);
|
|
||||||
fseek(cdimage_buffer, 0, SEEK_SET);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//SysPrintf("ReadSectorArchSector: %u(%u)\n", sector, sector*CD_FRAMESIZE_RAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO what causes req sector to be greater than CD size?
|
|
||||||
r = cdimg_read_func_archive(cdimage_buffer, base, dest, sector);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
int handlearchive(const char *isoname, s32* accurate_length) {
|
|
||||||
u32 read_size = accurate_length ? MSF2SECT(70, 70, 16) : MSF2SECT(0, 0, 16);
|
|
||||||
int ret = -1;
|
|
||||||
if ((ret = aropen(cdHandle, isoname)) == 0) {
|
|
||||||
cdimg_read_func = cdread_archive;
|
|
||||||
SysPrintf("[+archive]");
|
|
||||||
if (!ecm_file_detected) {
|
|
||||||
#ifndef ENABLE_ECM_FULL
|
|
||||||
//Detect ECM inside archive
|
|
||||||
cdimg_read_func_archive = cdread_normal;
|
|
||||||
cdread_archive(cdHandle, 0, cdbuffer, read_size);
|
|
||||||
if (handleecm("test.ecm", cdimage_buffer, accurate_length) != -1) {
|
|
||||||
cdimg_read_func_archive = cdread_ecm_decode;
|
|
||||||
cdimg_read_func = cdread_archive;
|
|
||||||
SysPrintf("[+ecm]");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SysPrintf("[+ecm]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int aropen(FILE* fparchive, const char* _fn) { return -1; }
|
|
||||||
static int cdread_archive(FILE *f, unsigned int base, void *dest, int sector) { return -1; }
|
|
||||||
int handlearchive(const char *isoname, s32* accurate_length) { return -1; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this function tries to get the .cue file of the given .bin
|
// this function tries to get the .cue file of the given .bin
|
||||||
// the necessary data is put into the ti (trackinformation)-array
|
// the necessary data is put into the ti (trackinformation)-array
|
||||||
static int parsecue(const char *isofile) {
|
static int parsecue(const char *isofile) {
|
||||||
|
@ -717,9 +634,8 @@ static int parsecue(const char *isofile) {
|
||||||
|
|
||||||
// Send to decoder if not lazy decoding
|
// Send to decoder if not lazy decoding
|
||||||
if (!lazy_decode) {
|
if (!lazy_decode) {
|
||||||
do_decode_cdda(&(ti[numtracks]), numtracks);
|
SysPrintf("\n");
|
||||||
fseek(ti[numtracks].handle, 0, SEEK_END);
|
file_len = do_decode_cdda(&(ti[numtracks]), numtracks) / CD_FRAMESIZE_RAW;
|
||||||
file_len = ftell(ti[numtracks].handle) / CD_FRAMESIZE_RAW; // accurate length
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1646,6 +1562,157 @@ int handleecm(const char *isoname, FILE* cdh, s32* accurate_length) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int (*cdimg_read_func_archive)(FILE *f, unsigned int base, void *dest, int sector) = NULL;
|
||||||
|
#ifdef HAVE_LIBARCHIVE
|
||||||
|
#include <archive.h>
|
||||||
|
#include <archive_entry.h>
|
||||||
|
|
||||||
|
struct archive *a = NULL;
|
||||||
|
u32 len_uncompressed_buffer = 0;
|
||||||
|
void *cdimage_buffer_mem = NULL;
|
||||||
|
FILE* cdimage_buffer = NULL; //cdHandle to store file
|
||||||
|
|
||||||
|
int aropen(FILE* fparchive, const char* _fn) {
|
||||||
|
s32 r;
|
||||||
|
u64 length = 0, length_peek;
|
||||||
|
boolean use_temp_file = FALSE; // TODO make a config param
|
||||||
|
static struct archive_entry *ae=NULL;
|
||||||
|
struct archive_entry *ae_peek;
|
||||||
|
|
||||||
|
if (a == NULL && cdimage_buffer == NULL) {
|
||||||
|
// We open file twice. First to peek sizes. This nastyness due used interface.
|
||||||
|
a = archive_read_new();
|
||||||
|
// r = archive_read_support_filter_all(a);
|
||||||
|
r = archive_read_support_format_all(a);
|
||||||
|
//r = archive_read_support_filter_all(a);
|
||||||
|
//r = archive_read_support_format_raw(a);
|
||||||
|
//r = archive_read_open_FILE(a, archive);
|
||||||
|
archive_read_open_filename(a, _fn, 75*CD_FRAMESIZE_RAW);
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
SysPrintf("Archive open failed (%i).\n", r);
|
||||||
|
archive_read_free(a);
|
||||||
|
a = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Get the biggest file in archive
|
||||||
|
while ((r=archive_read_next_header(a, &ae_peek)) == ARCHIVE_OK) {
|
||||||
|
length_peek = archive_entry_size(ae_peek);
|
||||||
|
//printf("Entry canditate %s %i\n", archive_entry_pathname(ae_peek), length_peek);
|
||||||
|
length = MAX(length_peek, length);
|
||||||
|
ae = (ae == NULL ? ae_peek : ae);
|
||||||
|
}
|
||||||
|
archive_read_free(a);
|
||||||
|
if (ae == NULL) {
|
||||||
|
SysPrintf("Archive entry read failed (%i).\n", r);
|
||||||
|
a = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//Now really open the file
|
||||||
|
a = archive_read_new();
|
||||||
|
// r = archive_read_support_compression_all(a);
|
||||||
|
r = archive_read_support_format_all(a);
|
||||||
|
archive_read_open_filename(a, _fn, 75*CD_FRAMESIZE_RAW);
|
||||||
|
while ((r=archive_read_next_header(a, &ae)) == ARCHIVE_OK) {
|
||||||
|
length_peek = archive_entry_size(ae);
|
||||||
|
if (length_peek == length) {
|
||||||
|
//ae = ae_peek;
|
||||||
|
SysPrintf(" -- Selected entry %s %i", archive_entry_pathname(ae), length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len_uncompressed_buffer = length?length:700*1024*1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_temp_file && (cdimage_buffer == NULL || cdHandle != cdimage_buffer)) {
|
||||||
|
cdimage_buffer = fopen("/tmp/pcsxr.tmp.bin", "w+b");
|
||||||
|
}
|
||||||
|
else if (!use_temp_file && (cdimage_buffer == NULL || cdHandle != cdimage_buffer)) {
|
||||||
|
if (cdimage_buffer_mem == NULL && ((cdimage_buffer_mem = malloc(len_uncompressed_buffer)) == NULL)) {
|
||||||
|
SysMessage("Could not reserve enough memory for full image buffer.\n");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
//printf("Memory ok2 %u %p\n", len_uncompressed_buffer, cdimage_buffer_mem);
|
||||||
|
cdimage_buffer = fmemopen(cdimage_buffer_mem, len_uncompressed_buffer, "w+b");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdHandle != cdimage_buffer) {
|
||||||
|
fclose(cdHandle); // opened thru archive so this not needed anymore
|
||||||
|
cdHandle = cdimage_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cdread_archive(FILE *f, unsigned int base, void *dest, int sector)
|
||||||
|
{
|
||||||
|
s32 r;
|
||||||
|
size_t size;
|
||||||
|
size_t readsize;
|
||||||
|
static off_t offset = 0; // w/o read always or static/ftell
|
||||||
|
const void *buff;
|
||||||
|
|
||||||
|
// If not pointing to archive file but CDDA file or some other track
|
||||||
|
if(f != cdHandle) {
|
||||||
|
return cdimg_read_func_archive(f, base, dest, sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump if already completely read
|
||||||
|
if (a != NULL /*&& (ecm_file_detected || sector*CD_FRAMESIZE_RAW <= len_uncompressed_buffer)*/) {
|
||||||
|
readsize = (sector+1) * CD_FRAMESIZE_RAW;
|
||||||
|
for (fseek(cdimage_buffer, offset, SEEK_SET); offset < readsize;) {
|
||||||
|
r = archive_read_data_block(a, &buff, &size, &offset);
|
||||||
|
offset += size;
|
||||||
|
SysPrintf("ReadArchive seek:%u(%u) cur:%u(%u)\r", sector, readsize/1024, offset/CD_FRAMESIZE_RAW, offset/1024);
|
||||||
|
fwrite(buff, size, 1, cdimage_buffer);
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
//SysPrintf("End of archive.\n");
|
||||||
|
archive_read_free(a);
|
||||||
|
a = NULL;
|
||||||
|
readsize = offset;
|
||||||
|
fflush(cdimage_buffer);
|
||||||
|
fseek(cdimage_buffer, 0, SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//SysPrintf("ReadSectorArchSector: %u(%u)\n", sector, sector*CD_FRAMESIZE_RAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO what causes req sector to be greater than CD size?
|
||||||
|
r = cdimg_read_func_archive(cdimage_buffer, base, dest, sector);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
int handlearchive(const char *isoname, s32* accurate_length) {
|
||||||
|
u32 read_size = accurate_length?MSF2SECT(70,70,16) : MSF2SECT(0,0,16);
|
||||||
|
int ret = -1;
|
||||||
|
if ((ret=aropen(cdHandle, isoname)) == 0) {
|
||||||
|
cdimg_read_func = cdread_archive;
|
||||||
|
SysPrintf("[+archive]");
|
||||||
|
if (!ecm_file_detected) {
|
||||||
|
#ifndef ENABLE_ECM_FULL
|
||||||
|
//Detect ECM inside archive
|
||||||
|
cdimg_read_func_archive = cdread_normal;
|
||||||
|
cdread_archive(cdHandle, 0, cdbuffer, read_size);
|
||||||
|
if (handleecm("test.ecm", cdimage_buffer, accurate_length) != -1) {
|
||||||
|
cdimg_read_func_archive = cdread_ecm_decode;
|
||||||
|
cdimg_read_func = cdread_archive;
|
||||||
|
SysPrintf("[+ecm]");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
SysPrintf("[+ecm]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int aropen(FILE* fparchive, const char* _fn) {return -1;}
|
||||||
|
static int cdread_archive(FILE *f, unsigned int base, void *dest, int sector) {return -1;}
|
||||||
|
int handlearchive(const char *isoname, s32* accurate_length) {return -1;}
|
||||||
|
#endif
|
||||||
|
|
||||||
static unsigned char * CALLBACK ISOgetBuffer_compr(void) {
|
static unsigned char * CALLBACK ISOgetBuffer_compr(void) {
|
||||||
return compr_img->buff_raw[compr_img->sector_in_blk] + 12;
|
return compr_img->buff_raw[compr_img->sector_in_blk] + 12;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue