Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
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 Libav.
6
*
7
* Libav 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
* Libav 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 Libav; 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
int
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
int
i;
63
64
/* Read the file header. */
65
avio_rb32
(pb);
/* Skip Magic. */
66
thp->
version
=
avio_rb32
(pb);
67
68
avio_rb32
(pb);
/* Max buf size. */
69
avio_rb32
(pb);
/* Max samples. */
70
71
thp->
fps
=
av_d2q
(
av_int2float
(
avio_rb32
(pb)), INT_MAX);
72
thp->
framecnt
=
avio_rb32
(pb);
73
thp->
first_framesz
=
avio_rb32
(pb);
74
avio_rb32
(pb);
/* Data size. */
75
76
thp->
compoff
=
avio_rb32
(pb);
77
avio_rb32
(pb);
/* offsetDataOffset. */
78
thp->
first_frame
=
avio_rb32
(pb);
79
thp->
last_frame
=
avio_rb32
(pb);
80
81
thp->
next_framesz
= thp->
first_framesz
;
82
thp->
next_frame
= thp->
first_frame
;
83
84
/* Read the component structure. */
85
avio_seek
(pb, thp->
compoff
, SEEK_SET);
86
thp->
compcount
=
avio_rb32
(pb);
87
88
/* Read the list of component types. */
89
avio_read
(pb, thp->
components
, 16);
90
91
for
(i = 0; i < thp->
compcount
; i++) {
92
if
(thp->
components
[i] == 0) {
93
if
(thp->
vst
!= 0)
94
break
;
95
96
/* Video component. */
97
st =
avformat_new_stream
(s,
NULL
);
98
if
(!st)
99
return
AVERROR
(ENOMEM);
100
101
/* The denominator and numerator are switched because 1/fps
102
is required. */
103
avpriv_set_pts_info
(st, 64, thp->
fps
.
den
, thp->
fps
.
num
);
104
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
105
st->
codec
->
codec_id
=
AV_CODEC_ID_THP
;
106
st->
codec
->
codec_tag
= 0;
/* no fourcc */
107
st->
codec
->
width
=
avio_rb32
(pb);
108
st->
codec
->
height
=
avio_rb32
(pb);
109
st->
codec
->
sample_rate
=
av_q2d
(thp->
fps
);
110
thp->
vst
= st;
111
thp->
video_stream_index
= st->
index
;
112
113
if
(thp->
version
== 0x11000)
114
avio_rb32
(pb);
/* Unknown. */
115
}
else
if
(thp->
components
[i] == 1) {
116
if
(thp->
has_audio
!= 0)
117
break
;
118
119
/* Audio component. */
120
st =
avformat_new_stream
(s,
NULL
);
121
if
(!st)
122
return
AVERROR
(ENOMEM);
123
124
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
125
st->
codec
->
codec_id
=
AV_CODEC_ID_ADPCM_THP
;
126
st->
codec
->
codec_tag
= 0;
/* no fourcc */
127
st->
codec
->
channels
=
avio_rb32
(pb);
/* numChannels. */
128
st->
codec
->
sample_rate
=
avio_rb32
(pb);
/* Frequency. */
129
130
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
131
132
thp->
audio_stream_index
= st->
index
;
133
thp->
has_audio
= 1;
134
}
135
}
136
137
return
0;
138
}
139
140
static
int
thp_read_packet
(
AVFormatContext
*s,
141
AVPacket
*pkt)
142
{
143
ThpDemuxContext
*thp = s->
priv_data
;
144
AVIOContext
*pb = s->
pb
;
145
int
size
;
146
int
ret;
147
148
if
(thp->
audiosize
== 0) {
149
/* Terminate when last frame is reached. */
150
if
(thp->
frame
>= thp->
framecnt
)
151
return
AVERROR
(EIO);
152
153
avio_seek
(pb, thp->
next_frame
, SEEK_SET);
154
155
/* Locate the next frame and read out its size. */
156
thp->
next_frame
+= thp->
next_framesz
;
157
thp->
next_framesz
=
avio_rb32
(pb);
158
159
avio_rb32
(pb);
/* Previous total size. */
160
size =
avio_rb32
(pb);
/* Total size of this frame. */
161
162
/* Store the audiosize so the next time this function is called,
163
the audio can be read. */
164
if
(thp->
has_audio
)
165
thp->
audiosize
=
avio_rb32
(pb);
/* Audio size. */
166
else
167
thp->
frame
++;
168
169
ret =
av_get_packet
(pb, pkt, size);
170
if
(ret != size) {
171
av_free_packet
(pkt);
172
return
AVERROR
(EIO);
173
}
174
175
pkt->
stream_index
= thp->
video_stream_index
;
176
}
else
{
177
ret =
av_get_packet
(pb, pkt, thp->
audiosize
);
178
if
(ret != thp->
audiosize
) {
179
av_free_packet
(pkt);
180
return
AVERROR
(EIO);
181
}
182
183
pkt->
stream_index
= thp->
audio_stream_index
;
184
if
(thp->
audiosize
>= 8)
185
pkt->
duration
=
AV_RB32
(&pkt->
data
[4]);
186
187
thp->
audiosize
= 0;
188
thp->
frame
++;
189
}
190
191
return
0;
192
}
193
194
AVInputFormat
ff_thp_demuxer
= {
195
.
name
=
"thp"
,
196
.long_name =
NULL_IF_CONFIG_SMALL
(
"THP"
),
197
.priv_data_size =
sizeof
(
ThpDemuxContext
),
198
.
read_probe
=
thp_probe
,
199
.
read_header
=
thp_read_header
,
200
.
read_packet
=
thp_read_packet
201
};
Generated on Tue Mar 1 2016 21:14:52 for Libav by
1.8.4