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
oggparsetheora.c
Go to the documentation of this file.
1
/**
2
Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi
3
4
Permission is hereby granted, free of charge, to any person
5
obtaining a copy of this software and associated documentation
6
files (the "Software"), to deal in the Software without
7
restriction, including without limitation the rights to use, copy,
8
modify, merge, publish, distribute, sublicense, and/or sell copies
9
of the Software, and to permit persons to whom the Software is
10
furnished to do so, subject to the following conditions:
11
12
The above copyright notice and this permission notice shall be
13
included in all copies or substantial portions of the Software.
14
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
DEALINGS IN THE SOFTWARE.
23
**/
24
25
#include <stdlib.h>
26
#include "
libavutil/bswap.h
"
27
#include "
libavcodec/get_bits.h
"
28
#include "
avformat.h
"
29
#include "
internal.h
"
30
#include "
oggdec.h
"
31
32
struct
theora_params
{
33
int
gpshift
;
34
int
gpmask
;
35
unsigned
version
;
36
};
37
38
static
int
39
theora_header
(
AVFormatContext
*
s
,
int
idx)
40
{
41
struct
ogg
*
ogg
= s->
priv_data
;
42
struct
ogg_stream
*os = ogg->
streams
+ idx;
43
AVStream
*st = s->
streams
[idx];
44
struct
theora_params
*thp = os->
private
;
45
int
cds = st->
codec
->
extradata_size
+ os->
psize
+ 2, err;
46
uint8_t
*cdp;
47
48
if
(!(os->
buf
[os->
pstart
] & 0x80))
49
return
0;
50
51
if
(!thp){
52
thp =
av_mallocz
(
sizeof
(*thp));
53
os->
private
= thp;
54
}
55
56
switch
(os->
buf
[os->
pstart
]) {
57
case
0x80: {
58
GetBitContext
gb;
59
int
width
,
height
;
60
AVRational
timebase;
61
62
init_get_bits
(&gb, os->
buf
+ os->
pstart
, os->
psize
*8);
63
64
skip_bits_long
(&gb, 7*8);
/* 0x80"theora" */
65
66
thp->
version
=
get_bits_long
(&gb, 24);
67
if
(thp->
version
< 0x030100)
68
{
69
av_log
(s,
AV_LOG_ERROR
,
70
"Too old or unsupported Theora (%x)\n"
, thp->
version
);
71
return
-1;
72
}
73
74
width =
get_bits
(&gb, 16) << 4;
75
height =
get_bits
(&gb, 16) << 4;
76
avcodec_set_dimensions
(st->
codec
, width, height);
77
78
if
(thp->
version
>= 0x030400)
79
skip_bits
(&gb, 100);
80
81
if
(thp->
version
>= 0x030200) {
82
width =
get_bits_long
(&gb, 24);
83
height =
get_bits_long
(&gb, 24);
84
if
( width <= st->codec->width && width > st->
codec
->
width
-16
85
&& height <= st->codec->height && height > st->
codec
->
height
-16)
86
avcodec_set_dimensions
(st->
codec
, width, height);
87
88
skip_bits
(&gb, 16);
89
}
90
timebase.
den
=
get_bits_long
(&gb, 32);
91
timebase.
num
=
get_bits_long
(&gb, 32);
92
if
(!(timebase.
num
> 0 && timebase.
den
> 0)) {
93
av_log
(s,
AV_LOG_WARNING
,
"Invalid time base in theora stream, assuming 25 FPS\n"
);
94
timebase.
num
= 1;
95
timebase.
den
= 25;
96
}
97
avpriv_set_pts_info
(st, 64, timebase.
num
, timebase.
den
);
98
99
st->
sample_aspect_ratio
.
num
=
get_bits_long
(&gb, 24);
100
st->
sample_aspect_ratio
.
den
=
get_bits_long
(&gb, 24);
101
102
if
(thp->
version
>= 0x030200)
103
skip_bits_long
(&gb, 38);
104
if
(thp->
version
>= 0x304000)
105
skip_bits
(&gb, 2);
106
107
thp->
gpshift
=
get_bits
(&gb, 5);
108
thp->
gpmask
= (1 << thp->
gpshift
) - 1;
109
110
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
111
st->
codec
->
codec_id
=
AV_CODEC_ID_THEORA
;
112
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
113
}
114
break
;
115
case
0x81:
116
ff_vorbis_comment
(s, &st->
metadata
, os->
buf
+ os->
pstart
+ 7, os->
psize
- 7);
117
case
0x82:
118
if
(!thp->
version
)
119
return
-1;
120
break
;
121
default
:
122
av_log
(s,
AV_LOG_ERROR
,
"Unknown header type %X\n"
, os->
buf
[os->
pstart
]);
123
return
-1;
124
}
125
126
if
((err =
av_reallocp
(&st->
codec
->
extradata
,
127
cds +
FF_INPUT_BUFFER_PADDING_SIZE
)) < 0) {
128
st->
codec
->
extradata_size
= 0;
129
return
err;
130
}
131
cdp = st->
codec
->
extradata
+ st->
codec
->
extradata_size
;
132
*cdp++ = os->
psize
>> 8;
133
*cdp++ = os->
psize
& 0xff;
134
memcpy (cdp, os->
buf
+ os->
pstart
, os->
psize
);
135
st->
codec
->
extradata_size
= cds;
136
137
return
1;
138
}
139
140
static
uint64_t
141
theora_gptopts
(
AVFormatContext
*ctx,
int
idx, uint64_t
gp
, int64_t *dts)
142
{
143
struct
ogg
*
ogg
= ctx->
priv_data
;
144
struct
ogg_stream
*os = ogg->
streams
+ idx;
145
struct
theora_params
*thp = os->
private
;
146
uint64_t iframe, pframe;
147
148
if
(!thp)
149
return
AV_NOPTS_VALUE
;
150
151
iframe = gp >> thp->
gpshift
;
152
pframe = gp & thp->
gpmask
;
153
154
if
(thp->
version
< 0x030201)
155
iframe++;
156
157
if
(!pframe)
158
os->
pflags
|=
AV_PKT_FLAG_KEY
;
159
160
if
(dts)
161
*dts = iframe + pframe;
162
163
return
iframe + pframe;
164
}
165
166
static
int
theora_packet
(
AVFormatContext
*
s
,
int
idx)
167
{
168
struct
ogg
*
ogg
= s->
priv_data
;
169
struct
ogg_stream
*os = ogg->
streams
+ idx;
170
int
duration
;
171
172
/* first packet handling
173
here we parse the duration of each packet in the first page and compare
174
the total duration to the page granule to find the encoder delay and
175
set the first timestamp */
176
177
if
((!os->
lastpts
|| os->
lastpts
==
AV_NOPTS_VALUE
) && !(os->
flags
&
OGG_FLAG_EOS
)) {
178
int
seg;
179
180
duration = 1;
181
for
(seg = os->
segp
; seg < os->
nsegs
; seg++) {
182
if
(os->
segments
[seg] < 255)
183
duration ++;
184
}
185
186
os->
lastpts
= os->
lastdts
=
theora_gptopts
(s, idx, os->
granule
, NULL) -
duration
;
187
if
(s->
streams
[idx]->
start_time
==
AV_NOPTS_VALUE
) {
188
s->
streams
[idx]->
start_time
= os->
lastpts
;
189
if
(s->
streams
[idx]->
duration
)
190
s->
streams
[idx]->
duration
-= s->
streams
[idx]->
start_time
;
191
}
192
}
193
194
/* parse packet duration */
195
if
(os->
psize
> 0) {
196
os->
pduration
= 1;
197
}
198
199
return
0;
200
}
201
202
const
struct
ogg_codec
ff_theora_codec
= {
203
.
magic
=
"\200theora"
,
204
.magicsize = 7,
205
.header =
theora_header
,
206
.packet =
theora_packet
,
207
.gptopts =
theora_gptopts
,
208
.nb_header = 3,
209
};
Generated on Sat Jan 25 2014 19:52:04 for FFmpeg by
1.8.2