]> git.sesse.net Git - ffmpeg/blob - libavformat/oggparsetheora.c
oggparsetheora: K&R cosmetics, reformat
[ffmpeg] / libavformat / oggparsetheora.c
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 "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         os->private = thp;
54     }
55
56     switch (os->buf[os->pstart]) {
57     case 0x80: {
58         GetBitContext gb;
59         int width, height;
60         AVRational timebase;
61
62         init_get_bits(&gb, os->buf + os->pstart, os->psize * 8);
63
64         /* 0x80"theora" */
65         skip_bits_long(&gb, 7 * 8);
66
67         thp->version = get_bits_long(&gb, 24);
68         if (thp->version < 0x030100) {
69             av_log(s, AV_LOG_ERROR,
70                    "Too old or unsupported Theora (%x)\n", thp->version);
71             return -1;
72         }
73
74         width  = get_bits(&gb, 16) << 4;
75         height = get_bits(&gb, 16) << 4;
76         avcodec_set_dimensions(st->codec, width, height);
77
78         if (thp->version >= 0x030400)
79             skip_bits(&gb, 100);
80
81         if (thp->version >= 0x030200) {
82             width  = get_bits_long(&gb, 24);
83             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                 avcodec_set_dimensions(st->codec, width, height);
87
88             skip_bits(&gb, 16);
89         }
90
91         timebase.den = get_bits_long(&gb, 32);
92         timebase.num = get_bits_long(&gb, 32);
93         if (!(timebase.num > 0 && timebase.den > 0)) {
94             av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
95             timebase.num = 1;
96             timebase.den = 25;
97         }
98         avpriv_set_pts_info(st, 64, timebase.num, timebase.den);
99
100         st->sample_aspect_ratio.num = get_bits_long(&gb, 24);
101         st->sample_aspect_ratio.den = get_bits_long(&gb, 24);
102
103         if (thp->version >= 0x030200)
104             skip_bits_long(&gb, 38);
105         if (thp->version >= 0x304000)
106             skip_bits(&gb, 2);
107
108         thp->gpshift = get_bits(&gb, 5);
109         thp->gpmask  = (1 << thp->gpshift) - 1;
110
111         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
112         st->codec->codec_id   = AV_CODEC_ID_THEORA;
113         st->need_parsing      = AVSTREAM_PARSE_HEADERS;
114     }
115     break;
116     case 0x81:
117         ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 7);
118     case 0x82:
119         if (!thp->version)
120             return -1;
121         break;
122     default:
123         return -1;
124     }
125
126     if ((err = av_reallocp(&st->codec->extradata,
127                            cds + FF_INPUT_BUFFER_PADDING_SIZE)) < 0) {
128         st->codec->extradata_size = 0;
129         return err;
130     }
131     cdp    = st->codec->extradata + st->codec->extradata_size;
132     *cdp++ = os->psize >> 8;
133     *cdp++ = os->psize & 0xff;
134     memcpy(cdp, os->buf + os->pstart, os->psize);
135     st->codec->extradata_size = cds;
136
137     return 1;
138 }
139
140 static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
141                                int64_t *dts)
142 {
143     struct ogg *ogg       = ctx->priv_data;
144     struct ogg_stream *os = ogg->streams + idx;
145     TheoraParams *thp     = os->private;
146     uint64_t iframe, pframe;
147
148     if (!thp)
149         return AV_NOPTS_VALUE;
150
151     iframe = gp >> thp->gpshift;
152     pframe = gp & thp->gpmask;
153
154     if (thp->version < 0x030201)
155         iframe++;
156
157     if (!pframe)
158         os->pflags |= AV_PKT_FLAG_KEY;
159
160     if (dts)
161         *dts = iframe + pframe;
162
163     return iframe + pframe;
164 }
165
166 const struct ogg_codec ff_theora_codec = {
167     .magic     = "\200theora",
168     .magicsize = 7,
169     .header    = theora_header,
170     .gptopts   = theora_gptopts,
171     .nb_header = 3,
172 };