Mercurial > libavformat.hg
annotate oggparsetheora.c @ 2505:81b1f6c373b4 libavformat
Make sure that the calculated duration doesn't decrease
author | conrad |
---|---|
date | Wed, 05 Sep 2007 00:25:40 +0000 |
parents | 3427d0c63a32 |
children | b22ba392ac21 |
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> | |
26 #include "avformat.h" | |
27 #include "bitstream.h" | |
28 #include "bswap.h" | |
29 #include "ogg2.h" | |
30 | |
31 typedef struct theora_params { | |
32 int gpshift; | |
33 int gpmask; | |
34 } theora_params_t; | |
35 | |
36 static int | |
37 theora_header (AVFormatContext * s, int idx) | |
38 { | |
39 ogg_t *ogg = s->priv_data; | |
40 ogg_stream_t *os = ogg->streams + idx; | |
41 AVStream *st = s->streams[idx]; | |
42 theora_params_t *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
|
43 int cds = st->codec->extradata_size + os->psize + 2; |
755 | 44 uint8_t *cdp; |
45 | |
758 | 46 if(!(os->buf[os->pstart] & 0x80)) |
755 | 47 return 0; |
48 | |
49 if(!thp){ | |
887 | 50 thp = av_mallocz(sizeof(*thp)); |
51 os->private = thp; | |
755 | 52 } |
53 | |
54 if (os->buf[os->pstart] == 0x80) { | |
55 GetBitContext gb; | |
2073
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
56 int width, height; |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
57 int version; |
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 | |
61 skip_bits(&gb, 7*8); /* 0x80"theora" */ | |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
62 |
2222 | 63 version = get_bits_long(&gb, 24); |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
64 if (version < 0x030100) |
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, |
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
67 "Too old or unsupported Theora (%x)\n", 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 |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
75 if (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 |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
78 width = get_bits_long(&gb, 24); |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
79 height = get_bits_long(&gb, 24); |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
80 if ( width <= st->codec->width && width > st->codec->width-16 |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
81 && height <= st->codec->height && height > st->codec->height-16) |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
82 avcodec_set_dimensions(st->codec, width, height); |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
83 |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
84 if (version >= 0x030200) |
59c2badf702a
fix display of theora videos with visible size smaller than encoded size
aurel
parents:
1178
diff
changeset
|
85 skip_bits(&gb, 16); |
2168 | 86 st->codec->time_base.den = get_bits_long(&gb, 32); |
87 st->codec->time_base.num = get_bits_long(&gb, 32); | |
1077 | 88 st->time_base = st->codec->time_base; |
885 | 89 |
2168 | 90 st->codec->sample_aspect_ratio.num = get_bits_long(&gb, 24); |
91 st->codec->sample_aspect_ratio.den = get_bits_long(&gb, 24); | |
755 | 92 |
970
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
93 if (version >= 0x030200) |
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
94 skip_bits(&gb, 38); |
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
95 if (version >= 0x304000) |
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
96 skip_bits(&gb, 2); |
2266681a4a52
support correct ptses on other than version 3.2.0 aswell
alex
parents:
887
diff
changeset
|
97 |
755 | 98 thp->gpshift = get_bits(&gb, 5); |
887 | 99 thp->gpmask = (1 << thp->gpshift) - 1; |
755 | 100 |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
758
diff
changeset
|
101 st->codec->codec_type = CODEC_TYPE_VIDEO; |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
758
diff
changeset
|
102 st->codec->codec_id = CODEC_ID_THEORA; |
755 | 103 |
104 } else if (os->buf[os->pstart] == 0x83) { | |
105 vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); | |
106 } | |
107 | |
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->extradata = av_realloc (st->codec->extradata, cds); |
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
758
diff
changeset
|
109 cdp = st->codec->extradata + st->codec->extradata_size; |
755 | 110 *cdp++ = os->psize >> 8; |
111 *cdp++ = os->psize & 0xff; | |
112 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
|
113 st->codec->extradata_size = cds; |
755 | 114 |
758 | 115 return 1; |
755 | 116 } |
117 | |
118 static uint64_t | |
119 theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp) | |
120 { | |
121 ogg_t *ogg = ctx->priv_data; | |
122 ogg_stream_t *os = ogg->streams + idx; | |
123 theora_params_t *thp = os->private; | |
124 uint64_t iframe = gp >> thp->gpshift; | |
125 uint64_t pframe = gp & thp->gpmask; | |
126 | |
1077 | 127 return iframe + pframe; |
755 | 128 } |
129 | |
130 ogg_codec_t theora_codec = { | |
131 .magic = "\200theora", | |
132 .magicsize = 7, | |
133 .header = theora_header, | |
134 .gptopts = theora_gptopts | |
135 }; |