|
|
|
@ -42,19 +42,6 @@ |
|
|
|
|
XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \
|
|
|
|
|
XMV_AUDIO_ADPCM51_REARLEFTRIGHT) |
|
|
|
|
|
|
|
|
|
typedef struct XMVAudioTrack { |
|
|
|
|
uint16_t compression; |
|
|
|
|
uint16_t channels; |
|
|
|
|
uint32_t sample_rate; |
|
|
|
|
uint16_t bits_per_sample; |
|
|
|
|
uint32_t bit_rate; |
|
|
|
|
uint16_t flags; |
|
|
|
|
uint16_t block_align; |
|
|
|
|
uint16_t block_samples; |
|
|
|
|
|
|
|
|
|
enum CodecID codec_id; |
|
|
|
|
} XMVAudioTrack; |
|
|
|
|
|
|
|
|
|
typedef struct XMVVideoPacket { |
|
|
|
|
/* The decoder stream index for this video packet. */ |
|
|
|
|
int stream_index; |
|
|
|
@ -79,8 +66,16 @@ typedef struct XMVAudioPacket { |
|
|
|
|
/* The decoder stream index for this audio packet. */ |
|
|
|
|
int stream_index; |
|
|
|
|
|
|
|
|
|
/* The audio track this packet encodes. */ |
|
|
|
|
XMVAudioTrack *track; |
|
|
|
|
uint16_t compression; |
|
|
|
|
uint16_t channels; |
|
|
|
|
uint32_t sample_rate; |
|
|
|
|
uint16_t bits_per_sample; |
|
|
|
|
uint32_t bit_rate; |
|
|
|
|
uint16_t flags; |
|
|
|
|
uint16_t block_align; |
|
|
|
|
uint16_t block_samples; |
|
|
|
|
|
|
|
|
|
enum CodecID codec_id; |
|
|
|
|
|
|
|
|
|
uint32_t data_size; |
|
|
|
|
uint64_t data_offset; |
|
|
|
@ -93,8 +88,6 @@ typedef struct XMVAudioPacket { |
|
|
|
|
typedef struct XMVDemuxContext { |
|
|
|
|
uint16_t audio_track_count; |
|
|
|
|
|
|
|
|
|
XMVAudioTrack *audio_tracks; |
|
|
|
|
|
|
|
|
|
uint32_t this_packet_size; |
|
|
|
|
uint32_t next_packet_size; |
|
|
|
|
|
|
|
|
@ -172,34 +165,28 @@ static int xmv_read_header(AVFormatContext *s, |
|
|
|
|
|
|
|
|
|
avio_skip(pb, 2); /* Unknown (padding?) */ |
|
|
|
|
|
|
|
|
|
xmv->audio_tracks = av_malloc(xmv->audio_track_count * sizeof(XMVAudioTrack)); |
|
|
|
|
if (!xmv->audio_tracks) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket)); |
|
|
|
|
if (!xmv->audio) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) { |
|
|
|
|
XMVAudioTrack *track = &xmv->audio_tracks[audio_track]; |
|
|
|
|
XMVAudioPacket *packet = &xmv->audio [audio_track]; |
|
|
|
|
XMVAudioPacket *packet = &xmv->audio[audio_track]; |
|
|
|
|
AVStream *ast = NULL; |
|
|
|
|
|
|
|
|
|
track->compression = avio_rl16(pb); |
|
|
|
|
track->channels = avio_rl16(pb); |
|
|
|
|
track->sample_rate = avio_rl32(pb); |
|
|
|
|
track->bits_per_sample = avio_rl16(pb); |
|
|
|
|
track->flags = avio_rl16(pb); |
|
|
|
|
|
|
|
|
|
track->bit_rate = track->bits_per_sample * |
|
|
|
|
track->sample_rate * |
|
|
|
|
track->channels; |
|
|
|
|
track->block_align = 36 * track->channels; |
|
|
|
|
track->block_samples = 64; |
|
|
|
|
track->codec_id = ff_wav_codec_get_id(track->compression, |
|
|
|
|
track->bits_per_sample); |
|
|
|
|
|
|
|
|
|
packet->track = track; |
|
|
|
|
packet->compression = avio_rl16(pb); |
|
|
|
|
packet->channels = avio_rl16(pb); |
|
|
|
|
packet->sample_rate = avio_rl32(pb); |
|
|
|
|
packet->bits_per_sample = avio_rl16(pb); |
|
|
|
|
packet->flags = avio_rl16(pb); |
|
|
|
|
|
|
|
|
|
packet->bit_rate = packet->bits_per_sample * |
|
|
|
|
packet->sample_rate * |
|
|
|
|
packet->channels; |
|
|
|
|
packet->block_align = 36 * packet->channels; |
|
|
|
|
packet->block_samples = 64; |
|
|
|
|
packet->codec_id = ff_wav_codec_get_id(packet->compression, |
|
|
|
|
packet->bits_per_sample); |
|
|
|
|
|
|
|
|
|
packet->stream_index = -1; |
|
|
|
|
|
|
|
|
|
packet->frame_size = 0; |
|
|
|
@ -207,24 +194,24 @@ static int xmv_read_header(AVFormatContext *s, |
|
|
|
|
|
|
|
|
|
/* TODO: ADPCM'd 5.1 sound is encoded in three separate streams.
|
|
|
|
|
* Those need to be interleaved to a proper 5.1 stream. */ |
|
|
|
|
if (track->flags & XMV_AUDIO_ADPCM51) |
|
|
|
|
if (packet->flags & XMV_AUDIO_ADPCM51) |
|
|
|
|
av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream " |
|
|
|
|
"(0x%04X)\n", track->flags); |
|
|
|
|
"(0x%04X)\n", packet->flags); |
|
|
|
|
|
|
|
|
|
ast = av_new_stream(s, audio_track); |
|
|
|
|
if (!ast) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
|
|
|
|
|
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; |
|
|
|
|
ast->codec->codec_id = track->codec_id; |
|
|
|
|
ast->codec->codec_tag = track->compression; |
|
|
|
|
ast->codec->channels = track->channels; |
|
|
|
|
ast->codec->sample_rate = track->sample_rate; |
|
|
|
|
ast->codec->bits_per_coded_sample = track->bits_per_sample; |
|
|
|
|
ast->codec->bit_rate = track->bit_rate; |
|
|
|
|
ast->codec->block_align = 36 * track->channels; |
|
|
|
|
ast->codec->codec_id = packet->codec_id; |
|
|
|
|
ast->codec->codec_tag = packet->compression; |
|
|
|
|
ast->codec->channels = packet->channels; |
|
|
|
|
ast->codec->sample_rate = packet->sample_rate; |
|
|
|
|
ast->codec->bits_per_coded_sample = packet->bits_per_sample; |
|
|
|
|
ast->codec->bit_rate = packet->bit_rate; |
|
|
|
|
ast->codec->block_align = 36 * packet->channels; |
|
|
|
|
|
|
|
|
|
av_set_pts_info(ast, 32, track->block_samples, track->sample_rate); |
|
|
|
|
av_set_pts_info(ast, 32, packet->block_samples, packet->sample_rate); |
|
|
|
|
|
|
|
|
|
packet->stream_index = ast->index; |
|
|
|
|
|
|
|
|
@ -339,7 +326,7 @@ static int xmv_process_packet_header(AVFormatContext *s) |
|
|
|
|
|
|
|
|
|
/** Carve up the audio data in frame_count slices */ |
|
|
|
|
packet->frame_size = packet->data_size / xmv->video.frame_count; |
|
|
|
|
packet->frame_size -= packet->frame_size % packet->track->block_align; |
|
|
|
|
packet->frame_size -= packet->frame_size % packet->block_align; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Packet data offsets */ |
|
|
|
@ -443,7 +430,7 @@ static int xmv_fetch_audio_packet(AVFormatContext *s, |
|
|
|
|
|
|
|
|
|
/* Calculate the PTS */ |
|
|
|
|
|
|
|
|
|
block_count = data_size / audio->track->block_align; |
|
|
|
|
block_count = data_size / audio->block_align; |
|
|
|
|
|
|
|
|
|
pkt->duration = block_count; |
|
|
|
|
pkt->pts = audio->block_count; |
|
|
|
@ -560,7 +547,6 @@ static int xmv_read_close(AVFormatContext *s) |
|
|
|
|
XMVDemuxContext *xmv = s->priv_data; |
|
|
|
|
|
|
|
|
|
av_free(xmv->audio); |
|
|
|
|
av_free(xmv->audio_tracks); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|