FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
oggparsetheora.c
Go to the documentation of this file.
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 struct theora_params {
33  int gpshift;
34  int gpmask;
35  unsigned version;
36 };
37 
38 static int
40 {
41  struct ogg *ogg = s->priv_data;
42  struct ogg_stream *os = ogg->streams + idx;
43  AVStream *st = s->streams[idx];
44  struct theora_params *thp = os->private;
45  int cds = st->codec->extradata_size + os->psize + 2;
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  skip_bits_long(&gb, 7*8); /* 0x80"theora" */
65 
66  thp->version = get_bits_long(&gb, 24);
67  if (thp->version < 0x030100)
68  {
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  timebase.den = get_bits_long(&gb, 32);
91  timebase.num = get_bits_long(&gb, 32);
92  if (!(timebase.num > 0 && timebase.den > 0)) {
93  av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
94  timebase.num = 1;
95  timebase.den = 25;
96  }
97  avpriv_set_pts_info(st, 64, timebase.num, timebase.den);
98 
99  st->sample_aspect_ratio.num = get_bits_long(&gb, 24);
100  st->sample_aspect_ratio.den = get_bits_long(&gb, 24);
101 
102  if (thp->version >= 0x030200)
103  skip_bits_long(&gb, 38);
104  if (thp->version >= 0x304000)
105  skip_bits(&gb, 2);
106 
107  thp->gpshift = get_bits(&gb, 5);
108  thp->gpmask = (1 << thp->gpshift) - 1;
109 
113  }
114  break;
115  case 0x81:
116  ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 7);
117  case 0x82:
118  if (!thp->version)
119  return -1;
120  break;
121  default:
122  av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
123  return -1;
124  }
125 
128  cdp = st->codec->extradata + st->codec->extradata_size;
129  *cdp++ = os->psize >> 8;
130  *cdp++ = os->psize & 0xff;
131  memcpy (cdp, os->buf + os->pstart, os->psize);
132  st->codec->extradata_size = cds;
133 
134  return 1;
135 }
136 
137 static uint64_t
138 theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
139 {
140  struct ogg *ogg = ctx->priv_data;
141  struct ogg_stream *os = ogg->streams + idx;
142  struct theora_params *thp = os->private;
143  uint64_t iframe, pframe;
144 
145  if (!thp)
146  return AV_NOPTS_VALUE;
147 
148  iframe = gp >> thp->gpshift;
149  pframe = gp & thp->gpmask;
150 
151  if (thp->version < 0x030201)
152  iframe++;
153 
154  if(!pframe)
155  os->pflags |= AV_PKT_FLAG_KEY;
156 
157  if (dts)
158  *dts = iframe + pframe;
159 
160  return iframe + pframe;
161 }
162 
163 static int theora_packet(AVFormatContext *s, int idx)
164 {
165  struct ogg *ogg = s->priv_data;
166  struct ogg_stream *os = ogg->streams + idx;
167  int duration;
168 
169  /* first packet handling
170  here we parse the duration of each packet in the first page and compare
171  the total duration to the page granule to find the encoder delay and
172  set the first timestamp */
173 
174  if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
175  int seg;
176 
177  duration = 1;
178  for (seg = os->segp; seg < os->nsegs; seg++) {
179  if (os->segments[seg] < 255)
180  duration ++;
181  }
182 
183  os->lastpts = os->lastdts = theora_gptopts(s, idx, os->granule, NULL) - duration;
184  if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
185  s->streams[idx]->start_time = os->lastpts;
186  if (s->streams[idx]->duration)
187  s->streams[idx]->duration -= s->streams[idx]->start_time;
188  }
189  }
190 
191  /* parse packet duration */
192  if (os->psize > 0) {
193  os->pduration = 1;
194  }
195 
196  return 0;
197 }
198 
199 const struct ogg_codec ff_theora_codec = {
200  .magic = "\200theora",
201  .magicsize = 7,
202  .header = theora_header,
203  .packet = theora_packet,
204  .gptopts = theora_gptopts,
205  .nb_header = 3,
206 };