Mercurial > libavformat.hg
annotate oggparsetheora.c @ 6211:6f6ecca6904a libavformat
In mov demuxer, only set sar if not already set, patch by Andrew Wason,
rectalogic at rectalogic dot com
Fixes issue #1754
author | bcoudurier |
---|---|
date | Thu, 01 Jul 2010 23:18:27 +0000 |
parents | 11bb10c37225 |
children |
rev | line source |
---|---|
755 | 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 | 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> | |
3286 | 26 #include "libavutil/bswap.h" |
4872 | 27 #include "libavcodec/get_bits.h" |
755 | 28 #include "avformat.h" |
2714 | 29 #include "oggdec.h" |
755 | 30 |
4016 | 31 struct theora_params { |
755 | 32 int gpshift; |
33 int gpmask; | |
4017 | 34 unsigned version; |
4016 | 35 }; |
755 | 36 |
37 static int | |
38 theora_header (AVFormatContext * s, int idx) | |
39 { | |
4016 | 40 struct ogg *ogg = s->priv_data; |
41 struct ogg_stream *os = ogg->streams + idx; | |
755 | 42 AVStream *st = s->streams[idx]; |
4016 | 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 | 45 uint8_t *cdp; |
46 | |
758 | 47 if(!(os->buf[os->pstart] & 0x80)) |
755 | 48 return 0; |
49 | |
50 if(!thp){ | |
887 | 51 thp = av_mallocz(sizeof(*thp)); |
52 os->private = thp; | |
755 | 53 } |
54 | |
55 if (os->buf[os->pstart] == 0x80) { | |
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 | 59 init_get_bits(&gb, os->buf + os->pstart, os->psize*8); |
60 | |
4935 | 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 | 63 thp->version = get_bits_long(&gb, 24); |
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 | 67 "Too old or unsupported Theora (%x)\n", thp->version); |
758 | 68 return -1; |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
69 } |
758 | 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 | 74 |
4017 | 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 | 78 if (thp->version >= 0x030200) { |
3965 | 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); | |
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 | 87 st->codec->time_base.den = get_bits_long(&gb, 32); |
88 st->codec->time_base.num = get_bits_long(&gb, 32); | |
5089 | 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 } | |
1077 | 94 st->time_base = st->codec->time_base; |
885 | 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 | 98 |
4017 | 99 if (thp->version >= 0x030200) |
4935 | 100 skip_bits_long(&gb, 38); |
4017 | 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 | 104 thp->gpshift = get_bits(&gb, 5); |
887 | 105 thp->gpmask = (1 << thp->gpshift) - 1; |
755 | 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 | 110 |
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 | 113 } |
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 | 118 *cdp++ = os->psize >> 8; |
119 *cdp++ = os->psize & 0xff; | |
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 | 122 |
758 | 123 return 1; |
755 | 124 } |
125 | |
126 static uint64_t | |
5514 | 127 theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts) |
755 | 128 { |
4016 | 129 struct ogg *ogg = ctx->priv_data; |
130 struct ogg_stream *os = ogg->streams + idx; | |
131 struct theora_params *thp = os->private; | |
755 | 132 uint64_t iframe = gp >> thp->gpshift; |
133 uint64_t pframe = gp & thp->gpmask; | |
134 | |
4017 | 135 if (thp->version < 0x030201) |
136 iframe++; | |
137 | |
2732 | 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 | 140 |
5514 | 141 if (dts) |
142 *dts = iframe + pframe; | |
143 | |
1077 | 144 return iframe + pframe; |
755 | 145 } |
146 | |
4016 | 147 const struct ogg_codec ff_theora_codec = { |
755 | 148 .magic = "\200theora", |
149 .magicsize = 7, | |
150 .header = theora_header, | |
151 .gptopts = theora_gptopts | |
152 }; |