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