FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
thp.c
Go to the documentation of this file.
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
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/intfloat.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
27
typedef
struct
ThpDemuxContext
{
28
int
version
;
29
unsigned
first_frame
;
30
unsigned
first_framesz
;
31
unsigned
last_frame
;
32
int
compoff
;
33
unsigned
framecnt
;
34
AVRational
fps
;
35
unsigned
frame
;
36
int64_t
next_frame
;
37
unsigned
next_framesz
;
38
int
video_stream_index
;
39
int
audio_stream_index
;
40
int
compcount
;
41
unsigned
char
components
[16];
42
AVStream
*
vst
;
43
int
has_audio
;
44
unsigned
audiosize
;
45
}
ThpDemuxContext
;
46
47
48
static
int
thp_probe
(
AVProbeData
*p)
49
{
50
double
d;
51
/* check file header */
52
if
(
AV_RL32
(p->
buf
) !=
MKTAG
(
'T'
,
'H'
,
'P'
,
'\0'
))
53
return
0;
54
55
d =
av_int2float
(
AV_RB32
(p->
buf
+ 16));
56
if
(d < 0.1 || d > 1000 ||
isnan
(d))
57
return
AVPROBE_SCORE_MAX
/4;
58
59
return
AVPROBE_SCORE_MAX
;
60
}
61
62
static
int
thp_read_header
(
AVFormatContext
*
s
)
63
{
64
ThpDemuxContext
*thp = s->
priv_data
;
65
AVStream
*st;
66
AVIOContext
*pb = s->
pb
;
67
int64_t fsize=
avio_size
(pb);
68
int
i;
69
70
/* Read the file header. */
71
avio_rb32
(pb);
/* Skip Magic. */
72
thp->
version
=
avio_rb32
(pb);
73
74
avio_rb32
(pb);
/* Max buf size. */
75
avio_rb32
(pb);
/* Max samples. */
76
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))
82
pb->
maxsize
= fsize;
83
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);
88
89
thp->
next_framesz
= thp->
first_framesz
;
90
thp->
next_frame
= thp->
first_frame
;
91
92
/* Read the component structure. */
93
avio_seek
(pb, thp->
compoff
, SEEK_SET);
94
thp->
compcount
=
avio_rb32
(pb);
95
96
/* Read the list of component types. */
97
avio_read
(pb, thp->
components
, 16);
98
99
for
(i = 0; i < thp->
compcount
; i++) {
100
if
(thp->
components
[i] == 0) {
101
if
(thp->
vst
)
102
break
;
103
104
/* Video component. */
105
st =
avformat_new_stream
(s,
NULL
);
106
if
(!st)
107
return
AVERROR
(ENOMEM);
108
109
/* The denominator and numerator are switched because 1/fps
110
is required. */
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);
117
st->
nb_frames
=
118
st->
duration
= thp->
framecnt
;
119
thp->
vst
= st;
120
thp->
video_stream_index
= st->
index
;
121
122
if
(thp->
version
== 0x11000)
123
avio_rb32
(pb);
/* Unknown. */
124
}
else
if
(thp->
components
[i] == 1) {
125
if
(thp->
has_audio
!= 0)
126
break
;
127
128
/* Audio component. */
129
st =
avformat_new_stream
(s,
NULL
);
130
if
(!st)
131
return
AVERROR
(ENOMEM);
132
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. */
138
139
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
140
141
thp->
audio_stream_index
= st->
index
;
142
thp->
has_audio
= 1;
143
}
144
}
145
146
return
0;
147
}
148
149
static
int
thp_read_packet
(
AVFormatContext
*
s
,
150
AVPacket
*
pkt
)
151
{
152
ThpDemuxContext
*thp = s->
priv_data
;
153
AVIOContext
*pb = s->
pb
;
154
unsigned
int
size
;
155
int
ret
;
156
157
if
(thp->
audiosize
== 0) {
158
/* Terminate when last frame is reached. */
159
if
(thp->
frame
>= thp->
framecnt
)
160
return
AVERROR_EOF
;
161
162
avio_seek
(pb, thp->
next_frame
, SEEK_SET);
163
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);
167
168
avio_rb32
(pb);
/* Previous total size. */
169
size =
avio_rb32
(pb);
/* Total size of this frame. */
170
171
/* Store the audiosize so the next time this function is called,
172
the audio can be read. */
173
if
(thp->
has_audio
)
174
thp->
audiosize
=
avio_rb32
(pb);
/* Audio size. */
175
else
176
thp->
frame
++;
177
178
ret =
av_get_packet
(pb, pkt, size);
179
if
(ret < 0)
180
return
ret
;
181
if
(ret != size) {
182
av_free_packet
(pkt);
183
return
AVERROR
(EIO);
184
}
185
186
pkt->
stream_index
= thp->
video_stream_index
;
187
}
else
{
188
ret =
av_get_packet
(pb, pkt, thp->
audiosize
);
189
if
(ret < 0)
190
return
ret
;
191
if
(ret != thp->
audiosize
) {
192
av_free_packet
(pkt);
193
return
AVERROR
(EIO);
194
}
195
196
pkt->
stream_index
= thp->
audio_stream_index
;
197
if
(thp->
audiosize
>= 8)
198
pkt->
duration
=
AV_RB32
(&pkt->
data
[4]);
199
200
thp->
audiosize
= 0;
201
thp->
frame
++;
202
}
203
204
return
0;
205
}
206
207
AVInputFormat
ff_thp_demuxer
= {
208
.
name
=
"thp"
,
209
.long_name =
NULL_IF_CONFIG_SMALL
(
"THP"
),
210
.priv_data_size =
sizeof
(
ThpDemuxContext
),
211
.
read_probe
=
thp_probe
,
212
.
read_header
=
thp_read_header
,
213
.
read_packet
=
thp_read_packet
214
};
Generated on Sun Mar 8 2015 02:35:13 for FFmpeg by
1.8.2