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