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
if
(os->
buf
[os->
pstart
] == 0x80) {
57
GetBitContext
gb;
58
int
width
,
height
;
59
60
init_get_bits
(&gb, os->
buf
+ os->
pstart
, os->
psize
*8);
61
62
skip_bits_long
(&gb, 7*8);
/* 0x80"theora" */
63
64
thp->
version
=
get_bits_long
(&gb, 24);
65
if
(thp->
version
< 0x030100)
66
{
67
av_log
(s,
AV_LOG_ERROR
,
68
"Too old or unsupported Theora (%x)\n"
, thp->
version
);
69
return
-1;
70
}
71
72
width =
get_bits
(&gb, 16) << 4;
73
height =
get_bits
(&gb, 16) << 4;
74
avcodec_set_dimensions
(st->
codec
, width, height);
75
76
if
(thp->
version
>= 0x030400)
77
skip_bits
(&gb, 100);
78
79
if
(thp->
version
>= 0x030200) {
80
width =
get_bits_long
(&gb, 24);
81
height =
get_bits_long
(&gb, 24);
82
if
( width <= st->codec->width && width > st->
codec
->
width
-16
83
&& height <= st->codec->height && height > st->
codec
->
height
-16)
84
avcodec_set_dimensions
(st->
codec
, width, height);
85
86
skip_bits
(&gb, 16);
87
}
88
st->
codec
->
time_base
.
den
=
get_bits_long
(&gb, 32);
89
st->
codec
->
time_base
.
num
=
get_bits_long
(&gb, 32);
90
if
(!(st->
codec
->
time_base
.
num
> 0 && st->
codec
->
time_base
.
den
> 0)) {
91
av_log
(s,
AV_LOG_WARNING
,
"Invalid time base in theora stream, assuming 25 FPS\n"
);
92
st->
codec
->
time_base
.
num
= 1;
93
st->
codec
->
time_base
.
den
= 25;
94
}
95
avpriv_set_pts_info
(st, 64, st->
codec
->
time_base
.
num
, st->
codec
->
time_base
.
den
);
96
97
st->
sample_aspect_ratio
.
num
=
get_bits_long
(&gb, 24);
98
st->
sample_aspect_ratio
.
den
=
get_bits_long
(&gb, 24);
99
100
if
(thp->
version
>= 0x030200)
101
skip_bits_long
(&gb, 38);
102
if
(thp->
version
>= 0x304000)
103
skip_bits
(&gb, 2);
104
105
thp->
gpshift
=
get_bits
(&gb, 5);
106
thp->
gpmask
= (1 << thp->
gpshift
) - 1;
107
108
st->
codec
->
codec_type
=
AVMEDIA_TYPE_VIDEO
;
109
st->
codec
->
codec_id
=
CODEC_ID_THEORA
;
110
st->
need_parsing
=
AVSTREAM_PARSE_HEADERS
;
111
112
}
else
if
(os->
buf
[os->
pstart
] == 0x83) {
113
ff_vorbis_comment
(s, &st->
metadata
, os->
buf
+ os->
pstart
+ 7, os->
psize
- 8);
114
}
115
116
st->
codec
->
extradata
=
av_realloc
(st->
codec
->
extradata
,
117
cds +
FF_INPUT_BUFFER_PADDING_SIZE
);
118
cdp = st->
codec
->
extradata
+ st->
codec
->
extradata_size
;
119
*cdp++ = os->
psize
>> 8;
120
*cdp++ = os->
psize
& 0xff;
121
memcpy (cdp, os->
buf
+ os->
pstart
, os->
psize
);
122
st->
codec
->
extradata_size
= cds;
123
124
return
1;
125
}
126
127
static
uint64_t
128
theora_gptopts
(
AVFormatContext
*ctx,
int
idx, uint64_t
gp
, int64_t *dts)
129
{
130
struct
ogg
*
ogg
= ctx->
priv_data
;
131
struct
ogg_stream
*os = ogg->
streams
+ idx;
132
struct
theora_params
*thp = os->
private
;
133
uint64_t iframe = gp >> thp->
gpshift
;
134
uint64_t pframe = gp & thp->
gpmask
;
135
136
if
(thp->
version
< 0x030201)
137
iframe++;
138
139
if
(!pframe)
140
os->
pflags
|=
AV_PKT_FLAG_KEY
;
141
142
if
(dts)
143
*dts = iframe + pframe;
144
145
return
iframe + pframe;
146
}
147
148
const
struct
ogg_codec
ff_theora_codec
= {
149
.
magic
=
"\200theora"
,
150
.magicsize = 7,
151
.header =
theora_header
,
152
.gptopts =
theora_gptopts
153
};