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
/* 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
+=
FFMAX
(thp->
next_framesz
, 1);
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 Sat Jan 25 2014 19:52:05 for FFmpeg by
1.8.2