Improve UE4Opus/EAOpus encoder delay calculations

This commit is contained in:
bnnm 2018-09-27 23:31:03 +02:00
parent 3269649eec
commit d7c5c3feaf
4 changed files with 42 additions and 16 deletions

View File

@ -279,9 +279,12 @@ void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples);
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
ffmpeg_codec_data * init_ffmpeg_ue4_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
ffmpeg_codec_data * init_ffmpeg_ea_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
size_t ffmpeg_make_opus_header(uint8_t * buf, int buf_size, int channels, int skip, int sample_rate);
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile);
size_t ue4_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile);
size_t switch_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile);
size_t ue4_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile);
size_t ea_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile);
#endif

View File

@ -511,8 +511,38 @@ static size_t custom_opus_get_samples(off_t offset, size_t data_size, int sample
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
return custom_opus_get_samples(offset, data_size, sample_rate, streamFile, OPUS_SWITCH);
}
size_t ue4_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
return custom_opus_get_samples(offset, data_size, sample_rate, streamFile, OPUS_UE4);
static size_t custom_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile, opus_type_t type) {
uint8_t buf[4];
size_t skip_size;
switch(type) {
case OPUS_SWITCH:
skip_size = 0x08;
break;
case OPUS_UE4:
skip_size = 0x02;
break;
case OPUS_EA:
skip_size = 0x02;
break;
default:
return 0;
}
/* encoder delay seems fixed to 1/8 of samples per frame, but may need more testing */
read_streamfile(buf, offset+skip_size, 0x04, streamFile); /* at least 0x02 */
return opus_get_packet_samples(buf, 0x04) / 8;
}
size_t switch_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile) {
return custom_opus_get_encoder_delay(offset, streamFile, OPUS_SWITCH);
}
size_t ue4_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile) {
return custom_opus_get_encoder_delay(offset, streamFile, OPUS_UE4);
}
size_t ea_opus_get_encoder_delay(off_t offset, STREAMFILE *streamFile) {
return custom_opus_get_encoder_delay(offset, streamFile, OPUS_EA);
}
@ -541,11 +571,9 @@ fail:
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(streamFile, start_offset, data_size, channels, skip, sample_rate, OPUS_SWITCH);
}
ffmpeg_codec_data * init_ffmpeg_ue4_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(streamFile, start_offset, data_size, channels, skip, sample_rate, OPUS_UE4);
}
ffmpeg_codec_data * init_ffmpeg_ea_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(streamFile, start_offset, data_size, channels, skip, sample_rate, OPUS_EA);
}

View File

@ -666,7 +666,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
#ifdef VGM_USE_FFMPEG
case EAAC_CODEC_EAOPUS: { /* EAOpus (unknown FourCC) [FIFA 17 (PC), FIFA 19 (Switch)]*/
int skip = 0;//todo
int skip = 0;
size_t data_size;
/* We'll remove EA blocks and pass raw data to FFmpeg Opus decoder */
@ -674,6 +674,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
temp_streamFile = setup_eaac_streamfile(streamData, eaac.version, eaac.codec, eaac.streamed,0,0, eaac.stream_offset);
if (!temp_streamFile) goto fail;
skip = ea_opus_get_encoder_delay(0x00, temp_streamFile);
data_size = get_streamfile_size(temp_streamFile);
vgmstream->codec_data = init_ffmpeg_ea_opus(temp_streamFile, 0x00,data_size, vgmstream->channels, skip, vgmstream->sample_rate);

View File

@ -26,14 +26,12 @@ VGMSTREAM * init_vgmstream_ue4opus(STREAMFILE *streamFile) {
/* 0x0f(2): frame count */
loop_flag = 0;
/* UE4Opus encodes 60ms (music) or 120ms (voice) frames, and encoder delay seems 1/8
* of samples per frame (may be more complex but wave looks ok-ish) */
//todo does UE4 actually care about encoder delay?
skip = (60 * 48000 / 1000) / 8; /* 48000 is the internal/resampled rate */
start_offset = 0x11;
data_size = get_streamfile_size(streamFile) - start_offset;
/* usually uses 60ms for music (delay of 360 samples) */
skip = ue4_opus_get_encoder_delay(start_offset, streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
@ -49,10 +47,6 @@ VGMSTREAM * init_vgmstream_ue4opus(STREAMFILE *streamFile) {
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
if (vgmstream->num_samples == 0) {
vgmstream->num_samples = ue4_opus_get_samples(start_offset, data_size, vgmstream->sample_rate, streamFile) - skip;
}
}
#else
goto fail;