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
typedef
struct
TheoraParams
{
33
int
gpshift
;
34
int
gpmask
;
35
unsigned
version
;
36
}
TheoraParams
;
37
38
static
int
theora_header
(
AVFormatContext
*
s
,
int
idx)
39
{
40
struct
ogg
*
ogg
= s->
priv_data
;
41
struct
ogg_stream
*os = ogg->
streams
+ idx;
42
AVStream
*st = s->
streams
[idx];
43
TheoraParams
*thp = os->
private
;
44
int
cds = st->
codec
->
extradata_size
+ os->
psize
+ 2;
45
int
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
if
(!thp)
54
return
AVERROR
(ENOMEM);
55
os->
private
= thp;
56
}
57
58
switch
(os->
buf
[os->
pstart
]) {
59
case
0x80: {
60
GetBitContext
gb;
61
AVRational
timebase;
62
63
init_get_bits
(&gb, os->
buf
+ os->
pstart
, os->
psize
* 8);
64
65
/* 0x80"theora" */
66
skip_bits_long
(&gb, 7 * 8);
67
68
thp->
version
=
get_bits_long
(&gb, 24);
69
if
(thp->
version
< 0x030100) {
70
av_log
(s,
AV_LOG_ERROR
,
71
"Too old or unsupported Theora (%x)\n"
, thp->
version
);
72
return
AVERROR
(ENOSYS);
73
}
74
75
st->
codec
->
width
=
get_bits
(&gb, 16) << 4;
76
st->
codec
->
height
=
get_bits
(&gb, 16) << 4;
77
78
if
(thp->
version
>= 0x030400)
79
skip_bits
(&gb, 100);
80
81
if
(thp->
version
>= 0x030200) {
82
int
width
=
get_bits_long
(&gb, 24);
83
int
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
st->
codec
->
width
=
width
;
87
st->
codec
->
height
=
height
;
88
}
89
90
skip_bits
(&gb, 16);
91
}
92
93
timebase.
den
=
get_bits_long
(&gb, 32);
94
timebase.
num
=
get_bits_long
(&gb, 32);
95
if
(!(timebase.
num
> 0 && timebase.
den
> 0)) {
96
av_log
(s,
AV_LOG_WARNING
,
"Invalid time base in theora stream, assuming 25 FPS\n"
);
97
timebase.
num
= 1;
98
timebase.
den
= 25;
99
}
100
avpriv_set_pts_info
(st, 64, timebase.
num
, timebase.
den
);
101
102
st->
sample_aspect_ratio
.
num
=
get_bits_long
(&gb, 24);
103
st->
sample_aspect_ratio
.
den
=
get_bits_long
(&gb, 24);
104
105
if
(thp->
version
>= 0x030200)
106
skip_bits_long
(&gb, 38);
107
if
(thp->
version
>= 0x304000)
108
skip_bits
(&gb, 2);
109
110
thp->
gpshift
=
get_bits
(&gb, 5);
111
thp->
gpmask
= (1 << thp->
gpshift
) - 1;
112
113
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
114
st->
codec
->
codec_id
=
AV_CODEC_ID_THEORA
;
115
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
116
}
117
break
;
118
case
0x81:
119
ff_vorbis_comment
(s, &st->
metadata
, os->
buf
+ os->
pstart
+ 7, os->
psize
- 7);
120
case
0x82:
121
if
(!thp->
version
)
122
return
AVERROR_INVALIDDATA
;
123
break
;
124
default
:
125
av_log
(s,
AV_LOG_ERROR
,
"Unknown header type %X\n"
, os->
buf
[os->
pstart
]);
126
return
AVERROR_INVALIDDATA
;
127
}
128
129
if
((err =
av_reallocp
(&st->
codec
->
extradata
,
130
cds +
FF_INPUT_BUFFER_PADDING_SIZE
)) < 0) {
131
st->
codec
->
extradata_size
= 0;
132
return
err;
133
}
134
memset(st->
codec
->
extradata
+ cds, 0,
FF_INPUT_BUFFER_PADDING_SIZE
);
135
136
cdp = st->
codec
->
extradata
+ st->
codec
->
extradata_size
;
137
*cdp++ = os->
psize
>> 8;
138
*cdp++ = os->
psize
& 0xff;
139
memcpy(cdp, os->
buf
+ os->
pstart
, os->
psize
);
140
st->
codec
->
extradata_size
= cds;
141
142
return
1;
143
}
144
145
static
uint64_t
theora_gptopts
(
AVFormatContext
*ctx,
int
idx, uint64_t
gp
,
146
int64_t *dts)
147
{
148
struct
ogg
*
ogg
= ctx->
priv_data
;
149
struct
ogg_stream
*os = ogg->
streams
+ idx;
150
TheoraParams
*thp = os->
private
;
151
uint64_t iframe, pframe;
152
153
if
(!thp)
154
return
AV_NOPTS_VALUE
;
155
156
iframe = gp >> thp->
gpshift
;
157
pframe = gp & thp->
gpmask
;
158
159
if
(thp->
version
< 0x030201)
160
iframe++;
161
162
if
(!pframe)
163
os->
pflags
|=
AV_PKT_FLAG_KEY
;
164
165
if
(dts)
166
*dts = iframe + pframe;
167
168
return
iframe + pframe;
169
}
170
171
static
int
theora_packet
(
AVFormatContext
*
s
,
int
idx)
172
{
173
struct
ogg
*
ogg
= s->
priv_data
;
174
struct
ogg_stream
*os = ogg->
streams
+ idx;
175
int
duration
;
176
177
/* first packet handling
178
here we parse the duration of each packet in the first page and compare
179
the total duration to the page granule to find the encoder delay and
180
set the first timestamp */
181
182
if
((!os->
lastpts
|| os->
lastpts
==
AV_NOPTS_VALUE
) && !(os->
flags
&
OGG_FLAG_EOS
)) {
183
int
seg;
184
185
duration = 1;
186
for
(seg = os->
segp
; seg < os->
nsegs
; seg++) {
187
if
(os->
segments
[seg] < 255)
188
duration ++;
189
}
190
191
os->
lastpts
= os->
lastdts
=
theora_gptopts
(s, idx, os->
granule
, NULL) -
duration
;
192
if
(s->
streams
[idx]->
start_time
==
AV_NOPTS_VALUE
) {
193
s->
streams
[idx]->
start_time
= os->
lastpts
;
194
if
(s->
streams
[idx]->
duration
)
195
s->
streams
[idx]->
duration
-= s->
streams
[idx]->
start_time
;
196
}
197
}
198
199
/* parse packet duration */
200
if
(os->
psize
> 0) {
201
os->
pduration
= 1;
202
}
203
204
return
0;
205
}
206
207
const
struct
ogg_codec
ff_theora_codec
= {
208
.
magic
=
"\200theora"
,
209
.magicsize = 7,
210
.header =
theora_header
,
211
.packet =
theora_packet
,
212
.gptopts =
theora_gptopts
,
213
.nb_header = 3,
214
};
Generated on Sun Mar 23 2014 23:50:12 for FFmpeg by
1.8.2