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
int
first_frame
;
30
int
first_framesz
;
31
int
last_frame
;
32
int
compoff
;
33
int
framecnt
;
34
AVRational
fps
;
35
int
frame
;
36
int
next_frame
;
37
int
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
/* check file header */
51
if
(
AV_RL32
(p->
buf
) ==
MKTAG
(
'T'
,
'H'
,
'P'
,
'\0'
))
52
return
AVPROBE_SCORE_MAX
;
53
else
54
return
0;
55
}
56
57
static
int
thp_read_header
(
AVFormatContext
*
s
)
58
{
59
ThpDemuxContext
*thp = s->
priv_data
;
60
AVStream
*st;
61
AVIOContext
*pb = s->
pb
;
62
int64_t fsize=
avio_size
(pb);
63
int
i;
64
65
/* Read the file header. */
66
avio_rb32
(pb);
/* Skip Magic. */
67
thp->
version
=
avio_rb32
(pb);
68
69
avio_rb32
(pb);
/* Max buf size. */
70
avio_rb32
(pb);
/* Max samples. */
71
72
thp->
fps
=
av_d2q
(
av_int2float
(
avio_rb32
(pb)), INT_MAX);
73
thp->
framecnt
=
avio_rb32
(pb);
74
thp->
first_framesz
=
avio_rb32
(pb);
75
pb->
maxsize
=
avio_rb32
(pb);
76
if
(fsize>0 && (!pb->
maxsize
|| fsize < pb->maxsize))
77
pb->
maxsize
= fsize;
78
79
thp->
compoff
=
avio_rb32
(pb);
80
avio_rb32
(pb);
/* offsetDataOffset. */
81
thp->
first_frame
=
avio_rb32
(pb);
82
thp->
last_frame
=
avio_rb32
(pb);
83
84
thp->
next_framesz
= thp->
first_framesz
;
85
thp->
next_frame
= thp->
first_frame
;
86
87
/* Read the component structure. */
88
avio_seek
(pb, thp->
compoff
, SEEK_SET);
89
thp->
compcount
=
avio_rb32
(pb);
90
91
/* Read the list of component types. */
92
avio_read
(pb, thp->
components
, 16);
93
94
for
(i = 0; i < thp->
compcount
; i++) {
95
if
(thp->
components
[i] == 0) {
96
if
(thp->
vst
!= 0)
97
break
;
98
99
/* Video component. */
100
st =
avformat_new_stream
(s, NULL);
101
if
(!st)
102
return
AVERROR
(ENOMEM);
103
104
/* The denominator and numerator are switched because 1/fps
105
is required. */
106
avpriv_set_pts_info
(st, 64, thp->
fps
.
den
, thp->
fps
.
num
);
107
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
108
st->
codec
->
codec_id
=
AV_CODEC_ID_THP
;
109
st->
codec
->
codec_tag
= 0;
/* no fourcc */
110
st->
codec
->
width
=
avio_rb32
(pb);
111
st->
codec
->
height
=
avio_rb32
(pb);
112
st->
codec
->
sample_rate
=
av_q2d
(thp->
fps
);
113
st->
nb_frames
=
114
st->
duration
= thp->
framecnt
;
115
thp->
vst
= st;
116
thp->
video_stream_index
= st->
index
;
117
118
if
(thp->
version
== 0x11000)
119
avio_rb32
(pb);
/* Unknown. */
120
}
else
if
(thp->
components
[i] == 1) {
121
if
(thp->
has_audio
!= 0)
122
break
;
123
124
/* Audio component. */
125
st =
avformat_new_stream
(s, NULL);
126
if
(!st)
127
return
AVERROR
(ENOMEM);
128
129
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
130
st->
codec
->
codec_id
=
AV_CODEC_ID_ADPCM_THP
;
131
st->
codec
->
codec_tag
= 0;
/* no fourcc */
132
st->
codec
->
channels
=
avio_rb32
(pb);
/* numChannels. */
133
st->
codec
->
sample_rate
=
avio_rb32
(pb);
/* Frequency. */
134
135
avpriv_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
AVIOContext
*pb = s->
pb
;
150
unsigned
int
size
;
151
int
ret
;
152
153
if
(thp->
audiosize
== 0) {
154
/* Terminate when last frame is reached. */
155
if
(thp->
frame
>= thp->
framecnt
)
156
return
AVERROR_EOF
;
157
158
avio_seek
(pb, thp->
next_frame
, SEEK_SET);
159
160
/* Locate the next frame and read out its size. */
161
thp->
next_frame
+= thp->
next_framesz
;
162
thp->
next_framesz
=
avio_rb32
(pb);
163
164
avio_rb32
(pb);
/* Previous total size. */
165
size =
avio_rb32
(pb);
/* Total size of this frame. */
166
167
/* Store the audiosize so the next time this function is called,
168
the audio can be read. */
169
if
(thp->
has_audio
)
170
thp->
audiosize
=
avio_rb32
(pb);
/* Audio size. */
171
else
172
thp->
frame
++;
173
174
ret =
av_get_packet
(pb, pkt, size);
175
if
(ret != size) {
176
av_free_packet
(pkt);
177
return
AVERROR
(EIO);
178
}
179
180
pkt->
stream_index
= thp->
video_stream_index
;
181
}
else
{
182
ret =
av_get_packet
(pb, pkt, thp->
audiosize
);
183
if
(ret != thp->
audiosize
) {
184
av_free_packet
(pkt);
185
return
AVERROR
(EIO);
186
}
187
188
pkt->
stream_index
= thp->
audio_stream_index
;
189
if
(thp->
audiosize
>= 8)
190
pkt->
duration
=
AV_RB32
(&pkt->
data
[4]);
191
192
thp->
audiosize
= 0;
193
thp->
frame
++;
194
}
195
196
return
0;
197
}
198
199
AVInputFormat
ff_thp_demuxer
= {
200
.
name
=
"thp"
,
201
.long_name =
NULL_IF_CONFIG_SMALL
(
"THP"
),
202
.priv_data_size =
sizeof
(
ThpDemuxContext
),
203
.
read_probe
=
thp_probe
,
204
.
read_header
=
thp_read_header
,
205
.
read_packet
=
thp_read_packet
206
};
Generated on Wed Jul 10 2013 23:48:14 for FFmpeg by
1.8.2