annotate oggparsetheora.c @ 6459:cf0ea082dad2 libavformat

Vorbis metadata writing. Patch by James Darnley <james.darnley gmail com>.
author rbultje
date Fri, 03 Sep 2010 19:30:27 +0000
parents 11bb10c37225
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
1 /**
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
2 Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
3
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
4 Permission is hereby granted, free of charge, to any person
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
5 obtaining a copy of this software and associated documentation
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
6 files (the "Software"), to deal in the Software without
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
7 restriction, including without limitation the rights to use, copy,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
8 modify, merge, publish, distribute, sublicense, and/or sell copies
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
9 of the Software, and to permit persons to whom the Software is
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
10 furnished to do so, subject to the following conditions:
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
11
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
12 The above copyright notice and this permission notice shall be
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
13 included in all copies or substantial portions of the Software.
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
14
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
22 DEALINGS IN THE SOFTWARE.
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
23 **/
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
24
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
25 #include <stdlib.h>
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 2732
diff changeset
26 #include "libavutil/bswap.h"
4872
304a0ea063f0 Rename bitstream.h to get_bits.h.
stefano
parents: 4017
diff changeset
27 #include "libavcodec/get_bits.h"
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
28 #include "avformat.h"
2714
b22ba392ac21 Rename ogg2.[ch] to oggdec.[ch].
diego
parents: 2222
diff changeset
29 #include "oggdec.h"
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
30
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
31 struct theora_params {
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
32 int gpshift;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
33 int gpmask;
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
34 unsigned version;
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
35 };
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
36
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
37 static int
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
38 theora_header (AVFormatContext * s, int idx)
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
39 {
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
40 struct ogg *ogg = s->priv_data;
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
41 struct ogg_stream *os = ogg->streams + idx;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
42 AVStream *st = s->streams[idx];
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
43 struct theora_params *thp = os->private;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 758
diff changeset
44 int cds = st->codec->extradata_size + os->psize + 2;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
45 uint8_t *cdp;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
46
758
7bbe565d50db check theora version
mru
parents: 755
diff changeset
47 if(!(os->buf[os->pstart] & 0x80))
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
48 return 0;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
49
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
50 if(!thp){
887
d70e50f1495f COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 885
diff changeset
51 thp = av_mallocz(sizeof(*thp));
d70e50f1495f COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 885
diff changeset
52 os->private = thp;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
53 }
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
54
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
55 if (os->buf[os->pstart] == 0x80) {
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
56 GetBitContext gb;
2073
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
57 int width, height;
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
58
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
59 init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
60
4935
a79015f8cd88 Use skip_bits_long() for large skips
conrad
parents: 4872
diff changeset
61 skip_bits_long(&gb, 7*8); /* 0x80"theora" */
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
62
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
63 thp->version = get_bits_long(&gb, 24);
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
64 if (thp->version < 0x030100)
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
65 {
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
66 av_log(s, AV_LOG_ERROR,
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
67 "Too old or unsupported Theora (%x)\n", thp->version);
758
7bbe565d50db check theora version
mru
parents: 755
diff changeset
68 return -1;
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
69 }
758
7bbe565d50db check theora version
mru
parents: 755
diff changeset
70
2073
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
71 width = get_bits(&gb, 16) << 4;
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
72 height = get_bits(&gb, 16) << 4;
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
73 avcodec_set_dimensions(st->codec, width, height);
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
74
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
75 if (thp->version >= 0x030400)
2073
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
76 skip_bits(&gb, 100);
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
77
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
78 if (thp->version >= 0x030200) {
3965
adbe373e6e79 Cosmetics: indentation
conrad
parents: 3964
diff changeset
79 width = get_bits_long(&gb, 24);
adbe373e6e79 Cosmetics: indentation
conrad
parents: 3964
diff changeset
80 height = get_bits_long(&gb, 24);
adbe373e6e79 Cosmetics: indentation
conrad
parents: 3964
diff changeset
81 if ( width <= st->codec->width && width > st->codec->width-16
adbe373e6e79 Cosmetics: indentation
conrad
parents: 3964
diff changeset
82 && height <= st->codec->height && height > st->codec->height-16)
adbe373e6e79 Cosmetics: indentation
conrad
parents: 3964
diff changeset
83 avcodec_set_dimensions(st->codec, width, height);
2073
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
84
59c2badf702a fix display of theora videos with visible size smaller than encoded size
aurel
parents: 1178
diff changeset
85 skip_bits(&gb, 16);
3964
66a7b9ab9e09 Visible width/height fields were added in Theora 3.2
conrad
parents: 3770
diff changeset
86 }
2168
d095666dedf3 use get_bits_long() where needed
mru
parents: 2073
diff changeset
87 st->codec->time_base.den = get_bits_long(&gb, 32);
d095666dedf3 use get_bits_long() where needed
mru
parents: 2073
diff changeset
88 st->codec->time_base.num = get_bits_long(&gb, 32);
5089
a8f6dd9abf72 Replace invalid Theora frame rate by 25 FPS.
reimar
parents: 5005
diff changeset
89 if (!(st->codec->time_base.num > 0 && st->codec->time_base.den > 0)) {
a8f6dd9abf72 Replace invalid Theora frame rate by 25 FPS.
reimar
parents: 5005
diff changeset
90 av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
a8f6dd9abf72 Replace invalid Theora frame rate by 25 FPS.
reimar
parents: 5005
diff changeset
91 st->codec->time_base.num = 1;
a8f6dd9abf72 Replace invalid Theora frame rate by 25 FPS.
reimar
parents: 5005
diff changeset
92 st->codec->time_base.den = 25;
a8f6dd9abf72 Replace invalid Theora frame rate by 25 FPS.
reimar
parents: 5005
diff changeset
93 }
1077
91677ac6fb19 set stream time_base properly
mru
parents: 970
diff changeset
94 st->time_base = st->codec->time_base;
885
da1d5db0ce5c COSMETICS: Remove all trailing whitespace.
diego
parents: 820
diff changeset
95
3759
27537074f2a9 convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents: 3286
diff changeset
96 st->sample_aspect_ratio.num = get_bits_long(&gb, 24);
27537074f2a9 convert every muxer/demuxer to write/read sample_aspect_ratio from/to
aurel
parents: 3286
diff changeset
97 st->sample_aspect_ratio.den = get_bits_long(&gb, 24);
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
98
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
99 if (thp->version >= 0x030200)
4935
a79015f8cd88 Use skip_bits_long() for large skips
conrad
parents: 4872
diff changeset
100 skip_bits_long(&gb, 38);
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
101 if (thp->version >= 0x304000)
970
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
102 skip_bits(&gb, 2);
2266681a4a52 support correct ptses on other than version 3.2.0 aswell
alex
parents: 887
diff changeset
103
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
104 thp->gpshift = get_bits(&gb, 5);
887
d70e50f1495f COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 885
diff changeset
105 thp->gpmask = (1 << thp->gpshift) - 1;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
106
5910
536e5527c1e0 Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 5824
diff changeset
107 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 758
diff changeset
108 st->codec->codec_id = CODEC_ID_THEORA;
5751
4d38b2c2bc59 oggdec: Parse theora headers since ogg might not mark keyframes
conrad
parents: 5514
diff changeset
109 st->need_parsing = AVSTREAM_PARSE_HEADERS;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
110
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
111 } else if (os->buf[os->pstart] == 0x83) {
5824
b9f21d75c81a oggdec: Metadata is per-stream; don't merge multiple streams' together
conrad
parents: 5823
diff changeset
112 ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8);
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
113 }
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
114
5005
53092c7684a2 Ensure that the extradata buffer is padded appripriately in the ogg demuxer.
conrad
parents: 4935
diff changeset
115 st->codec->extradata = av_realloc (st->codec->extradata,
53092c7684a2 Ensure that the extradata buffer is padded appripriately in the ogg demuxer.
conrad
parents: 4935
diff changeset
116 cds + FF_INPUT_BUFFER_PADDING_SIZE);
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 758
diff changeset
117 cdp = st->codec->extradata + st->codec->extradata_size;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
118 *cdp++ = os->psize >> 8;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
119 *cdp++ = os->psize & 0xff;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
120 memcpy (cdp, os->buf + os->pstart, os->psize);
820
feca73904e67 changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents: 758
diff changeset
121 st->codec->extradata_size = cds;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
122
758
7bbe565d50db check theora version
mru
parents: 755
diff changeset
123 return 1;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
124 }
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
125
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
126 static uint64_t
5514
52c7b29eca31 oggdec: Set dts when known
conrad
parents: 5089
diff changeset
127 theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
128 {
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
129 struct ogg *ogg = ctx->priv_data;
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
130 struct ogg_stream *os = ogg->streams + idx;
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
131 struct theora_params *thp = os->private;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
132 uint64_t iframe = gp >> thp->gpshift;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
133 uint64_t pframe = gp & thp->gpmask;
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
134
4017
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
135 if (thp->version < 0x030201)
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
136 iframe++;
b2a3ed76122e OGG: correct PTS with old theora streams
mru
parents: 4016
diff changeset
137
2732
2b101e9d25c0 set PKT_FLAG_KEY for Theora and OGM streams
mru
parents: 2714
diff changeset
138 if(!pframe)
5913
11bb10c37225 Replace all occurences of PKT_FLAG_KEY with AV_PKT_FLAG_KEY.
cehoyos
parents: 5910
diff changeset
139 os->pflags |= AV_PKT_FLAG_KEY;
2732
2b101e9d25c0 set PKT_FLAG_KEY for Theora and OGM streams
mru
parents: 2714
diff changeset
140
5514
52c7b29eca31 oggdec: Set dts when known
conrad
parents: 5089
diff changeset
141 if (dts)
52c7b29eca31 oggdec: Set dts when known
conrad
parents: 5089
diff changeset
142 *dts = iframe + pframe;
52c7b29eca31 oggdec: Set dts when known
conrad
parents: 5089
diff changeset
143
1077
91677ac6fb19 set stream time_base properly
mru
parents: 970
diff changeset
144 return iframe + pframe;
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
145 }
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
146
4016
6cd006bc2de9 OGG: untypedef demuxer structs
mru
parents: 3965
diff changeset
147 const struct ogg_codec ff_theora_codec = {
755
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
148 .magic = "\200theora",
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
149 .magicsize = 7,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
150 .header = theora_header,
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
151 .gptopts = theora_gptopts
27449ee55201 support theora in ogg, plus required ogg core changes
mru
parents:
diff changeset
152 };