ffmpeg / libavformat / thp.c @ d1e0d21f
History | View | Annotate | Download (5.75 KB)
1 |
/*
|
---|---|
2 |
* THP Demuxer
|
3 |
* Copyright (c) 2007 Marco Gerards.
|
4 |
*
|
5 |
* This file is part of FFmpeg.
|
6 |
*
|
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.
|
11 |
*
|
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.
|
16 |
*
|
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
|
20 |
*/
|
21 |
|
22 |
|
23 |
#include "avformat.h" |
24 |
#include "allformats.h" |
25 |
|
26 |
typedef struct ThpDemuxContext { |
27 |
int version;
|
28 |
int first_frame;
|
29 |
int first_framesz;
|
30 |
int last_frame;
|
31 |
int compoff;
|
32 |
int framecnt;
|
33 |
AVRational fps; |
34 |
int frame;
|
35 |
int next_frame;
|
36 |
int next_framesz;
|
37 |
int video_stream_index;
|
38 |
int audio_stream_index;
|
39 |
int compcount;
|
40 |
unsigned char components[16]; |
41 |
AVStream* vst; |
42 |
int has_audio;
|
43 |
int audiosize;
|
44 |
} ThpDemuxContext; |
45 |
|
46 |
|
47 |
static int thp_probe(AVProbeData *p) |
48 |
{ |
49 |
/* check file header */
|
50 |
if (p->buf_size < 4) |
51 |
return 0; |
52 |
|
53 |
if (AV_RL32(p->buf) == MKTAG('T', 'H', 'P', '\0')) |
54 |
return AVPROBE_SCORE_MAX;
|
55 |
else
|
56 |
return 0; |
57 |
} |
58 |
|
59 |
static int thp_read_header(AVFormatContext *s, |
60 |
AVFormatParameters *ap) |
61 |
{ |
62 |
ThpDemuxContext *thp = s->priv_data; |
63 |
AVStream *st; |
64 |
ByteIOContext *pb = &s->pb; |
65 |
int i;
|
66 |
|
67 |
/* Read the file header. */
|
68 |
|
69 |
get_be32(pb); /* Skip Magic. */
|
70 |
thp->version = get_be32(pb); |
71 |
|
72 |
get_be32(pb); /* Max buf size. */
|
73 |
get_be32(pb); /* Max samples. */
|
74 |
|
75 |
thp->fps = av_d2q(av_int2flt(get_be32(pb)), INT_MAX); |
76 |
thp->framecnt = get_be32(pb); |
77 |
thp->first_framesz = get_be32(pb); |
78 |
get_be32(pb); /* Data size. */
|
79 |
|
80 |
thp->compoff = get_be32(pb); |
81 |
get_be32(pb); /* offsetDataOffset. */
|
82 |
thp->first_frame = get_be32(pb); |
83 |
thp->last_frame = get_be32(pb); |
84 |
|
85 |
thp->next_framesz = thp->first_framesz; |
86 |
thp->next_frame = thp->first_frame; |
87 |
|
88 |
/* Read the component structure. */
|
89 |
url_fseek (pb, thp->compoff, SEEK_SET); |
90 |
thp->compcount = get_be32(pb); |
91 |
|
92 |
/* Read the list of component types. */
|
93 |
get_buffer(pb, thp->components, 16);
|
94 |
|
95 |
for (i = 0; i < thp->compcount; i++) { |
96 |
if (thp->components[i] == 0) { |
97 |
if (thp->vst != 0) |
98 |
break;
|
99 |
|
100 |
/* Video component. */
|
101 |
st = av_new_stream(s, 0);
|
102 |
if (!st)
|
103 |
return AVERROR_NOMEM;
|
104 |
|
105 |
/* The denominator and numerator are switched because 1/fps
|
106 |
is required. */
|
107 |
av_set_pts_info(st, 64, thp->fps.den, thp->fps.num);
|
108 |
st->codec->codec_type = CODEC_TYPE_VIDEO; |
109 |
st->codec->codec_id = CODEC_ID_THP; |
110 |
st->codec->codec_tag = 0; /* no fourcc */ |
111 |
st->codec->width = get_be32(pb); |
112 |
st->codec->height = get_be32(pb); |
113 |
st->codec->sample_rate = av_q2d(thp->fps); |
114 |
thp->vst = st; |
115 |
thp->video_stream_index = st->index; |
116 |
|
117 |
if (thp->version == 0x11000) |
118 |
get_be32(pb); /* Unknown. */
|
119 |
} |
120 |
else if (thp->components[i] == 1) { |
121 |
if (thp->has_audio != 0) |
122 |
break;
|
123 |
|
124 |
/* Audio component. */
|
125 |
st = av_new_stream(s, 0);
|
126 |
if (!st)
|
127 |
return AVERROR_NOMEM;
|
128 |
|
129 |
st->codec->codec_type = CODEC_TYPE_AUDIO; |
130 |
st->codec->codec_id = CODEC_ID_ADPCM_THP; |
131 |
st->codec->codec_tag = 0; /* no fourcc */ |
132 |
st->codec->channels = get_be32(pb); /* numChannels. */
|
133 |
st->codec->sample_rate = get_be32(pb); /* Frequency. */
|
134 |
|
135 |
av_set_pts_info(st, 64, 1, st->codec->sample_rate); |
136 |
|
137 |
thp->audio_stream_index = st->index; |
138 |
thp->has_audio = 1;
|
139 |
} |
140 |
} |
141 |
|
142 |
return 0; |
143 |
} |
144 |
|
145 |
static int thp_read_packet(AVFormatContext *s, |
146 |
AVPacket *pkt) |
147 |
{ |
148 |
ThpDemuxContext *thp = s->priv_data; |
149 |
ByteIOContext *pb = &s->pb; |
150 |
int size;
|
151 |
int ret;
|
152 |
|
153 |
if (thp->audiosize == 0) { |
154 |
|
155 |
/* Terminate when last frame is reached. */
|
156 |
if (thp->frame >= thp->framecnt)
|
157 |
return AVERROR_IO;
|
158 |
|
159 |
url_fseek(pb, thp->next_frame, SEEK_SET); |
160 |
|
161 |
/* Locate the next frame and read out its size. */
|
162 |
thp->next_frame += thp->next_framesz; |
163 |
thp->next_framesz = get_be32(pb); |
164 |
|
165 |
get_be32(pb); /* Previous total size. */
|
166 |
size = get_be32(pb); /* Total size of this frame. */
|
167 |
|
168 |
/* Store the audiosize so the next time this function is called,
|
169 |
the audio can be read. */
|
170 |
if (thp->has_audio)
|
171 |
thp->audiosize = get_be32(pb); /* Audio size. */
|
172 |
else
|
173 |
thp->frame++; |
174 |
|
175 |
ret = av_get_packet(pb, pkt, size); |
176 |
if (ret != size) {
|
177 |
av_free_packet(pkt); |
178 |
return AVERROR_IO;
|
179 |
} |
180 |
|
181 |
pkt->stream_index = thp->video_stream_index; |
182 |
} |
183 |
else {
|
184 |
ret = av_get_packet(pb, pkt, thp->audiosize); |
185 |
if (ret != thp->audiosize) {
|
186 |
av_free_packet(pkt); |
187 |
return AVERROR_IO;
|
188 |
} |
189 |
|
190 |
pkt->stream_index = thp->audio_stream_index; |
191 |
thp->audiosize = 0;
|
192 |
thp->frame++; |
193 |
} |
194 |
|
195 |
return 0; |
196 |
} |
197 |
|
198 |
AVInputFormat thp_demuxer = { |
199 |
"thp",
|
200 |
"THP",
|
201 |
sizeof(ThpDemuxContext),
|
202 |
thp_probe, |
203 |
thp_read_header, |
204 |
thp_read_packet |
205 |
}; |