Libav
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
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
return
AVERROR_INVALIDDATA
;
126
}
127
128
if
((err =
av_reallocp
(&st->
codec
->
extradata
,
129
cds +
FF_INPUT_BUFFER_PADDING_SIZE
)) < 0) {
130
st->
codec
->
extradata_size
= 0;
131
return
err;
132
}
133
cdp = st->
codec
->
extradata
+ st->
codec
->
extradata_size
;
134
*cdp++ = os->
psize
>> 8;
135
*cdp++ = os->
psize
& 0xff;
136
memcpy(cdp, os->
buf
+ os->
pstart
, os->
psize
);
137
st->
codec
->
extradata_size
= cds;
138
139
return
1;
140
}
141
142
static
uint64_t
theora_gptopts
(
AVFormatContext
*ctx,
int
idx, uint64_t gp,
143
int64_t *dts)
144
{
145
struct
ogg
*
ogg
= ctx->
priv_data
;
146
struct
ogg_stream
*os = ogg->
streams
+ idx;
147
TheoraParams
*thp = os->
private
;
148
uint64_t iframe, pframe;
149
150
if
(!thp)
151
return
AV_NOPTS_VALUE
;
152
153
iframe = gp >> thp->
gpshift
;
154
pframe = gp & thp->
gpmask
;
155
156
if
(thp->
version
< 0x030201)
157
iframe++;
158
159
if
(!pframe)
160
os->
pflags
|=
AV_PKT_FLAG_KEY
;
161
162
if
(dts)
163
*dts = iframe + pframe;
164
165
return
iframe + pframe;
166
}
167
168
const
struct
ogg_codec
ff_theora_codec
= {
169
.
magic
=
"\200theora"
,
170
.magicsize = 7,
171
.header =
theora_header
,
172
.gptopts =
theora_gptopts
,
173
.nb_header = 3,
174
};
Generated on Thu Sep 30 2021 23:03:20 for Libav by
1.8.1.2