FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
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;
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
st->
codec
->
extradata
=
av_realloc
(st->
codec
->
extradata
,
127
cds +
FF_INPUT_BUFFER_PADDING_SIZE
);
128
cdp = st->
codec
->
extradata
+ st->
codec
->
extradata_size
;
129
*cdp++ = os->
psize
>> 8;
130
*cdp++ = os->
psize
& 0xff;
131
memcpy (cdp, os->
buf
+ os->
pstart
, os->
psize
);
132
st->
codec
->
extradata_size
= cds;
133
134
return
1;
135
}
136
137
static
uint64_t
138
theora_gptopts
(
AVFormatContext
*ctx,
int
idx, uint64_t
gp
, int64_t *dts)
139
{
140
struct
ogg
*
ogg
= ctx->
priv_data
;
141
struct
ogg_stream
*os = ogg->
streams
+ idx;
142
struct
theora_params
*thp = os->
private
;
143
uint64_t iframe, pframe;
144
145
if
(!thp)
146
return
AV_NOPTS_VALUE
;
147
148
iframe = gp >> thp->
gpshift
;
149
pframe = gp & thp->
gpmask
;
150
151
if
(thp->
version
< 0x030201)
152
iframe++;
153
154
if
(!pframe)
155
os->
pflags
|=
AV_PKT_FLAG_KEY
;
156
157
if
(dts)
158
*dts = iframe + pframe;
159
160
return
iframe + pframe;
161
}
162
163
static
int
theora_packet
(
AVFormatContext
*s,
int
idx)
164
{
165
struct
ogg
*
ogg
= s->
priv_data
;
166
struct
ogg_stream
*os = ogg->
streams
+ idx;
167
int
duration
;
168
169
/* first packet handling
170
here we parse the duration of each packet in the first page and compare
171
the total duration to the page granule to find the encoder delay and
172
set the first timestamp */
173
174
if
((!os->
lastpts
|| os->
lastpts
==
AV_NOPTS_VALUE
) && !(os->
flags
&
OGG_FLAG_EOS
)) {
175
int
seg;
176
177
duration = 1;
178
for
(seg = os->
segp
; seg < os->
nsegs
; seg++) {
179
if
(os->
segments
[seg] < 255)
180
duration ++;
181
}
182
183
os->
lastpts
= os->
lastdts
=
theora_gptopts
(s, idx, os->
granule
,
NULL
) -
duration
;
184
if
(s->
streams
[idx]->
start_time
==
AV_NOPTS_VALUE
) {
185
s->
streams
[idx]->
start_time
= os->
lastpts
;
186
if
(s->
streams
[idx]->
duration
)
187
s->
streams
[idx]->
duration
-= s->
streams
[idx]->
start_time
;
188
}
189
}
190
191
/* parse packet duration */
192
if
(os->
psize
> 0) {
193
os->
pduration
= 1;
194
}
195
196
return
0;
197
}
198
199
const
struct
ogg_codec
ff_theora_codec
= {
200
.
magic
=
"\200theora"
,
201
.magicsize = 7,
202
.header =
theora_header
,
203
.packet =
theora_packet
,
204
.gptopts =
theora_gptopts
,
205
.nb_header = 3,
206
};
Generated on Sat May 25 2013 04:01:18 for FFmpeg by
1.8.2