]> git.sesse.net Git - ffmpeg/blob - libavformat/oggparsetheora.c
Merge commit '9765549f551ff40869aee1a6492b6a976c86cfe9'
[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->codecpar->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->codecpar->width  = get_bits(&gb, 16) << 4;
76         st->codecpar->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->codecpar->width  && width  > st->codecpar->width  - 16 &&
85                 height <= st->codecpar->height && height > st->codecpar->height - 16) {
86                 st->codecpar->width  = width;
87                 st->codecpar->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  = (1U << thp->gpshift) - 1;
112
113         st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
114         st->codecpar->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         av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
126         return AVERROR_INVALIDDATA;
127     }
128
129     if ((err = av_reallocp(&st->codecpar->extradata,
130                            cds + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
131         st->codecpar->extradata_size = 0;
132         return err;
133     }
134     memset(st->codecpar->extradata + cds, 0, AV_INPUT_BUFFER_PADDING_SIZE);
135
136     cdp    = st->codecpar->extradata + st->codecpar->extradata_size;
137     *cdp++ = os->psize >> 8;
138     *cdp++ = os->psize & 0xff;
139     memcpy(cdp, os->buf + os->pstart, os->psize);
140     st->codecpar->extradata_size = cds;
141
142     return 1;
143 }
144
145 static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
146                                int64_t *dts)
147 {
148     struct ogg *ogg       = ctx->priv_data;
149     struct ogg_stream *os = ogg->streams + idx;
150     TheoraParams *thp     = os->private;
151     uint64_t iframe, pframe;
152
153     if (!thp)
154         return AV_NOPTS_VALUE;
155
156     iframe = gp >> thp->gpshift;
157     pframe = gp & thp->gpmask;
158
159     if (thp->version < 0x030201)
160         iframe++;
161
162     if (!pframe)
163         os->pflags |= AV_PKT_FLAG_KEY;
164
165     if (dts)
166         *dts = iframe + pframe;
167
168     return iframe + pframe;
169 }
170
171 static int theora_packet(AVFormatContext *s, int idx)
172 {
173     struct ogg *ogg = s->priv_data;
174     struct ogg_stream *os = ogg->streams + idx;
175     int duration;
176
177     /* first packet handling
178        here we parse the duration of each packet in the first page and compare
179        the total duration to the page granule to find the encoder delay and
180        set the first timestamp */
181
182     if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
183         int seg;
184
185         duration = 1;
186         for (seg = os->segp; seg < os->nsegs; seg++) {
187             if (os->segments[seg] < 255)
188                 duration ++;
189         }
190
191         os->lastpts = os->lastdts   = theora_gptopts(s, idx, os->granule, NULL) - duration;
192         if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
193             s->streams[idx]->start_time = os->lastpts;
194             if (s->streams[idx]->duration > 0)
195                 s->streams[idx]->duration -= s->streams[idx]->start_time;
196         }
197     }
198
199     /* parse packet duration */
200     if (os->psize > 0) {
201         os->pduration = 1;
202     }
203
204     return 0;
205 }
206
207 const struct ogg_codec ff_theora_codec = {
208     .magic     = "\200theora",
209     .magicsize = 7,
210     .header    = theora_header,
211     .packet    = theora_packet,
212     .gptopts   = theora_gptopts,
213     .nb_header = 3,
214 };