Extend ffmpeg's make_riff_xma_from_fmt/fmt_chunk_swap_endian for XMA1

This commit is contained in:
bnnm 2017-03-19 00:43:31 +01:00
parent e021cff626
commit bcf93deecd
5 changed files with 58 additions and 30 deletions

View File

@ -164,12 +164,12 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample);
void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples);
/* ffmpeg_decoder_utils */
int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec);
int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, size_t chunk_size, uint16_t codec);
int ffmpeg_make_riff_atrac3(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay);
int ffmpeg_make_riff_atrac3plus(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay);
int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode);
int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size);
int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian);
int ffmpeg_make_riff_xma_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian);
int ffmpeg_make_riff_xwma(uint8_t * buf, size_t buf_size, int codec, size_t sample_count, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align);
/* XMA sample parser info (struct to avoid passing so much stuff, separate for reusing) */

View File

@ -256,7 +256,7 @@ int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, s
return riff_size;
}
int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian) {
int ffmpeg_make_riff_xma_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian) {
size_t riff_size = 4+4+ 4 + 4+4+fmt_size + 4+4;
uint8_t chunk[100];
@ -265,8 +265,10 @@ int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_off
if (read_streamfile(chunk,fmt_offset,fmt_size, streamFile) != fmt_size)
goto fail;
if (big_endian)
ffmpeg_fmt_chunk_swap_endian(chunk, 0x166);
if (big_endian) {
int codec = read_16bitBE(fmt_offset,streamFile);
ffmpeg_fmt_chunk_swap_endian(chunk, fmt_size, codec);
}
memcpy(buf+0x00, "RIFF", 4);
put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */
@ -313,10 +315,31 @@ int ffmpeg_make_riff_xwma(uint8_t * buf, size_t buf_size, int codec, size_t samp
}
int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec) {
if (codec != 0x166)/* XMA2 */
goto fail;
int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, size_t chunk_size, uint16_t codec) {
int i;
/* swap from LE to BE or the other way around, doesn't matter */
switch(codec) {
case 0x165: { /* XMA1 */
put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*FormatTag*/
put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*BitsPerSample*/
put_16bitLE(chunk + 0x04, get_16bitBE(chunk + 0x04));/*EncodeOptions*/
put_16bitLE(chunk + 0x06, get_16bitBE(chunk + 0x06));/*LargestSkip*/
put_16bitLE(chunk + 0x08, get_16bitBE(chunk + 0x08));/*NumStreams*/
// put_8bit(chunk + 0x0a, get_8bit(chunk + 0x0a));/*LoopCount*/
// put_8bit(chunk + 0x0b, get_8bit(chunk + 0x0b));/*Version*/
for (i = 0xc; i < chunk_size; i += 0x14) { /* reverse endianness for each stream */
put_32bitLE(chunk + i + 0x00, get_32bitBE(chunk + i + 0x00));/*PsuedoBytesPerSec*/
put_32bitLE(chunk + i + 0x04, get_32bitBE(chunk + i + 0x04));/*SampleRate*/
put_32bitLE(chunk + i + 0x08, get_32bitBE(chunk + i + 0x08));/*LoopStart*/
put_32bitLE(chunk + i + 0x0c, get_32bitBE(chunk + i + 0x0c));/*LoopEnd*/
// put_8bit(chunk + i + 0x10, get_8bit(chunk + i + 0x10));/*SubframeData*/
// put_8bit(chunk + i + 0x11, get_8bit(chunk + i + 0x11));/*Channels*/
put_16bitLE(chunk + i + 0x12, get_16bitBE(chunk + i + 0x12));/*ChannelMask*/
}
break;
}
case 0x166: { /* XMA2 */
put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*wFormatTag*/
put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*nChannels*/
put_32bitLE(chunk + 0x04, get_32bitBE(chunk + 0x04));/*nSamplesPerSec*/
@ -335,6 +358,11 @@ int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec) {
/* put_8bit(chunk + 0x30, get_8bit(chunk + 0x30));*//*LoopCount*/
/* put_8bit(chunk + 0x31, get_8bit(chunk + 0x31));*//*EncoderVersion*/
put_16bitLE(chunk + 0x32, get_16bitBE(chunk + 0x32));/*BlockCount*/
break;
}
default:
goto fail;
}
return 1;

View File

@ -113,7 +113,7 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {
if (!find_chunk_be(streamFileGSP, 0x584D4558,first_offset,1, &chunk_offset,NULL)) goto fail; /*"XMEX"*/
/* 0x00: fmt0x166 header (BE), 0x34: seek table */
bytes = ffmpeg_make_riff_xma2_from_fmt(buf,200, chunk_offset,0x34, datasize, streamFileGSP, 1);
bytes = ffmpeg_make_riff_xma_from_fmt(buf,200, chunk_offset,0x34, datasize, streamFileGSP, 1);
if (bytes <= 0) goto fail;
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);

View File

@ -350,7 +350,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
break;
#ifdef VGM_USE_FFMPEG
case 0xB:
/* XMA1/XMA2 */ /* Lightning Returns SFX, FFXIII (X360) */
/* XMA2 */ /* Lightning Returns SFX, FFXIII (X360) */
{
ffmpeg_codec_data *ffmpeg_data = NULL;
uint8_t buf[200];
@ -358,7 +358,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
/* post_meta_offset+0x00: fmt0x166 header (BE), post_meta_offset+0x34: seek table */
bytes = ffmpeg_make_riff_xma2_from_fmt(buf,200, post_meta_offset,0x34, stream_size, streamFile, 1);
bytes = ffmpeg_make_riff_xma_from_fmt(buf,200, post_meta_offset,0x34, stream_size, streamFile, 1);
if (bytes <= 0) goto fail;
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,stream_size);

View File

@ -385,7 +385,7 @@ static int create_riff_header(uint8_t * buf, size_t buf_size, xma_header_data *
internal_size = 4+4+xma->chunk_size;
if (xma->force_little_endian ) {
if ( !ffmpeg_fmt_chunk_swap_endian(chunk, xma->fmt_codec) )
if ( !ffmpeg_fmt_chunk_swap_endian(chunk, xma->chunk_size, xma->fmt_codec) )
goto fail;
}