3 * Copyright (c) 2007 Marco Gerards
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/intreadwrite.h"
23 #include "libavutil/intfloat.h"
27 typedef struct ThpDemuxContext
{
30 unsigned first_framesz
;
37 unsigned next_framesz
;
38 int video_stream_index
;
39 int audio_stream_index
;
41 unsigned char components
[16];
48 static int thp_probe(AVProbeData
*p
)
51 /* check file header */
52 if (AV_RL32(p
->buf
) != MKTAG('T', 'H', 'P', '\0'))
55 d
= av_int2float(AV_RB32(p
->buf
+ 16));
56 if (d
< 0.1 || d
> 1000 || isnan(d
))
57 return AVPROBE_SCORE_MAX
/4;
59 return AVPROBE_SCORE_MAX
;
62 static int thp_read_header(AVFormatContext
*s
)
64 ThpDemuxContext
*thp
= s
->priv_data
;
66 AVIOContext
*pb
= s
->pb
;
67 int64_t fsize
= avio_size(pb
);
70 /* Read the file header. */
71 avio_rb32(pb
); /* Skip Magic. */
72 thp
->version
= avio_rb32(pb
);
74 avio_rb32(pb
); /* Max buf size. */
75 avio_rb32(pb
); /* Max samples. */
77 thp
->fps
= av_d2q(av_int2float(avio_rb32(pb
)), INT_MAX
);
78 thp
->framecnt
= avio_rb32(pb
);
79 thp
->first_framesz
= avio_rb32(pb
);
80 pb
->maxsize
= avio_rb32(pb
);
81 if(fsize
>0 && (!pb
->maxsize
|| fsize
< pb
->maxsize
))
84 thp
->compoff
= avio_rb32(pb
);
85 avio_rb32(pb
); /* offsetDataOffset. */
86 thp
->first_frame
= avio_rb32(pb
);
87 thp
->last_frame
= avio_rb32(pb
);
89 thp
->next_framesz
= thp
->first_framesz
;
90 thp
->next_frame
= thp
->first_frame
;
92 /* Read the component structure. */
93 avio_seek (pb
, thp
->compoff
, SEEK_SET
);
94 thp
->compcount
= avio_rb32(pb
);
96 /* Read the list of component types. */
97 avio_read(pb
, thp
->components
, 16);
99 for (i
= 0; i
< thp
->compcount
; i
++) {
100 if (thp
->components
[i
] == 0) {
104 /* Video component. */
105 st
= avformat_new_stream(s
, NULL
);
107 return AVERROR(ENOMEM
);
109 /* The denominator and numerator are switched because 1/fps
111 avpriv_set_pts_info(st
, 64, thp
->fps
.den
, thp
->fps
.num
);
112 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
113 st
->codec
->codec_id
= AV_CODEC_ID_THP
;
114 st
->codec
->codec_tag
= 0; /* no fourcc */
115 st
->codec
->width
= avio_rb32(pb
);
116 st
->codec
->height
= avio_rb32(pb
);
118 st
->duration
= thp
->framecnt
;
120 thp
->video_stream_index
= st
->index
;
122 if (thp
->version
== 0x11000)
123 avio_rb32(pb
); /* Unknown. */
124 } else if (thp
->components
[i
] == 1) {
125 if (thp
->has_audio
!= 0)
128 /* Audio component. */
129 st
= avformat_new_stream(s
, NULL
);
131 return AVERROR(ENOMEM
);
133 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
134 st
->codec
->codec_id
= AV_CODEC_ID_ADPCM_THP
;
135 st
->codec
->codec_tag
= 0; /* no fourcc */
136 st
->codec
->channels
= avio_rb32(pb
); /* numChannels. */
137 st
->codec
->sample_rate
= avio_rb32(pb
); /* Frequency. */
139 avpriv_set_pts_info(st
, 64, 1, st
->codec
->sample_rate
);
141 thp
->audio_stream_index
= st
->index
;
149 static int thp_read_packet(AVFormatContext
*s
,
152 ThpDemuxContext
*thp
= s
->priv_data
;
153 AVIOContext
*pb
= s
->pb
;
157 if (thp
->audiosize
== 0) {
158 /* Terminate when last frame is reached. */
159 if (thp
->frame
>= thp
->framecnt
)
162 avio_seek(pb
, thp
->next_frame
, SEEK_SET
);
164 /* Locate the next frame and read out its size. */
165 thp
->next_frame
+= FFMAX(thp
->next_framesz
, 1);
166 thp
->next_framesz
= avio_rb32(pb
);
168 avio_rb32(pb
); /* Previous total size. */
169 size
= avio_rb32(pb
); /* Total size of this frame. */
171 /* Store the audiosize so the next time this function is called,
172 the audio can be read. */
174 thp
->audiosize
= avio_rb32(pb
); /* Audio size. */
178 ret
= av_get_packet(pb
, pkt
, size
);
184 pkt
->stream_index
= thp
->video_stream_index
;
186 ret
= av_get_packet(pb
, pkt
, thp
->audiosize
);
187 if (ret
!= thp
->audiosize
) {
192 pkt
->stream_index
= thp
->audio_stream_index
;
193 if (thp
->audiosize
>= 8)
194 pkt
->duration
= AV_RB32(&pkt
->data
[4]);
203 AVInputFormat ff_thp_demuxer
= {
205 .long_name
= NULL_IF_CONFIG_SMALL("THP"),
206 .priv_data_size
= sizeof(ThpDemuxContext
),
207 .read_probe
= thp_probe
,
208 .read_header
= thp_read_header
,
209 .read_packet
= thp_read_packet