summaryrefslogtreecommitdiff
path: root/libavformat/thp.c
diff options
context:
space:
mode:
authorMarco Gerards <mgerards@xs4all.nl>2007-04-07 16:03:23 +0000
committerDiego Biurrun <diego@biurrun.de>2007-04-07 16:03:23 +0000
commitd1e0d21f9492215b324fe7872e050b2d48a55c1d (patch)
tree3e67a6ef88f4f739cdf795e07399202e72a9fd89 /libavformat/thp.c
parentefd2afc2aef18e9c8d43a18dccc792d901528992 (diff)
THP PCM decoder, used on the Nintendo GameCube.
patch by Marco Gerards, mgerards xs4all nl Originally committed as revision 8646 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/thp.c')
-rw-r--r--libavformat/thp.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/libavformat/thp.c b/libavformat/thp.c
index d0d80428c4..1b7567e78e 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -35,10 +35,12 @@ typedef struct ThpDemuxContext {
int next_frame;
int next_framesz;
int video_stream_index;
+ int audio_stream_index;
int compcount;
unsigned char components[16];
AVStream* vst;
int has_audio;
+ int audiosize;
} ThpDemuxContext;
@@ -116,7 +118,23 @@ static int thp_read_header(AVFormatContext *s,
get_be32(pb); /* Unknown. */
}
else if (thp->components[i] == 1) {
- /* XXX: Required for audio playback. */
+ if (thp->has_audio != 0)
+ break;
+
+ /* Audio component. */
+ st = av_new_stream(s, 0);
+ if (!st)
+ return AVERROR_NOMEM;
+
+ st->codec->codec_type = CODEC_TYPE_AUDIO;
+ st->codec->codec_id = CODEC_ID_ADPCM_THP;
+ st->codec->codec_tag = 0; /* no fourcc */
+ st->codec->channels = get_be32(pb); /* numChannels. */
+ st->codec->sample_rate = get_be32(pb); /* Frequency. */
+
+ av_set_pts_info(st, 64, 1, st->codec->sample_rate);
+
+ thp->audio_stream_index = st->index;
thp->has_audio = 1;
}
}
@@ -132,6 +150,8 @@ static int thp_read_packet(AVFormatContext *s,
int size;
int ret;
+ if (thp->audiosize == 0) {
+
/* Terminate when last frame is reached. */
if (thp->frame >= thp->framecnt)
return AVERROR_IO;
@@ -145,8 +165,12 @@ static int thp_read_packet(AVFormatContext *s,
get_be32(pb); /* Previous total size. */
size = get_be32(pb); /* Total size of this frame. */
+ /* Store the audiosize so the next time this function is called,
+ the audio can be read. */
if (thp->has_audio)
- get_be32(pb); /* Audio size. */
+ thp->audiosize = get_be32(pb); /* Audio size. */
+ else
+ thp->frame++;
ret = av_get_packet(pb, pkt, size);
if (ret != size) {
@@ -155,7 +179,18 @@ static int thp_read_packet(AVFormatContext *s,
}
pkt->stream_index = thp->video_stream_index;
- thp->frame++;
+ }
+ else {
+ ret = av_get_packet(pb, pkt, thp->audiosize);
+ if (ret != thp->audiosize) {
+ av_free_packet(pkt);
+ return AVERROR_IO;
+ }
+
+ pkt->stream_index = thp->audio_stream_index;
+ thp->audiosize = 0;
+ thp->frame++;
+ }
return 0;
}