avformat/electronicarts: support ADPCM PSX

Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Paul B Mahol 2015-10-21 22:59:08 +02:00
parent 7ebe12fc55
commit 0d7c027483
1 changed files with 13 additions and 3 deletions

View File

@ -86,6 +86,8 @@ typedef struct EaDemuxContext {
int sample_rate; int sample_rate;
int num_channels; int num_channels;
int num_samples; int num_samples;
int platform;
} EaDemuxContext; } EaDemuxContext;
static uint32_t read_arbitrary(AVIOContext *pb) static uint32_t read_arbitrary(AVIOContext *pb)
@ -255,6 +257,8 @@ static int process_audio_header_elements(AVFormatContext *s)
return 0; return 0;
} }
if (ea->audio_codec == AV_CODEC_ID_NONE && ea->platform == 0x01)
ea->audio_codec = AV_CODEC_ID_ADPCM_PSX;
if (ea->sample_rate == -1) if (ea->sample_rate == -1)
ea->sample_rate = revision == 3 ? 48000 : 22050; ea->sample_rate = revision == 3 ? 48000 : 22050;
@ -387,10 +391,10 @@ static int process_ea_header(AVFormatContext *s)
blockid = avio_rl32(pb); blockid = avio_rl32(pb);
if (blockid == GSTR_TAG) { if (blockid == GSTR_TAG) {
avio_skip(pb, 4); avio_skip(pb, 4);
} else if ((blockid & 0xFFFF) != PT00_TAG) { } else if ((blockid & 0xFF) != (PT00_TAG & 0xFF)) {
avpriv_request_sample(s, "unknown SCHl headerid"); blockid = avio_rl32(pb);
return 0;
} }
ea->platform = (blockid >> 16) & 0xFF;
err = process_audio_header_elements(s); err = process_audio_header_elements(s);
break; break;
@ -600,6 +604,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
num_samples = avio_rl32(pb); num_samples = avio_rl32(pb);
avio_skip(pb, 8); avio_skip(pb, 8);
chunk_size -= 12; chunk_size -= 12;
} else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) {
avio_skip(pb, 8);
chunk_size -= 8;
} }
if (partial_packet) { if (partial_packet) {
@ -639,6 +646,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
case AV_CODEC_ID_MP3: case AV_CODEC_ID_MP3:
pkt->duration = num_samples; pkt->duration = num_samples;
break; break;
case AV_CODEC_ID_ADPCM_PSX:
pkt->duration = chunk_size / (16 * ea->num_channels) * 28;
break;
default: default:
pkt->duration = chunk_size / (ea->bytes * ea->num_channels); pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
} }