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