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
}
115
break
;
116
case
0x81:
117
ff_vorbis_comment
(s, &st->
metadata
, os->
buf
+ os->
pstart
+ 7, os->
psize
- 8);
118
case
0x82:
119
if
(!thp->
version
)
120
return
-1;
121
break
;
122
default
:
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
const
struct
ogg_codec
ff_theora_codec
= {
164
.
magic
=
"\200theora"
,
165
.magicsize = 7,
166
.header =
theora_header
,
167
.gptopts =
theora_gptopts
,
168
.nb_header = 3,
169
};