FFmpeg
1.2.4
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
oggparsetheora.c
Go to the documentation of this file.
1
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 Fri Nov 29 2013 19:15:19 for FFmpeg by
1.8.1.2