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 };
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition: oggdec.h:31
unsigned int pflags
Definition: oggdec.h:67
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:198
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi.
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:709
int num
numerator
Definition: rational.h:44
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:141
int flags
Definition: oggdec.h:76
int64_t lastpts
Definition: oggdec.h:72
Format I/O context.
Definition: avformat.h:944
unsigned int psize
Definition: oggdec.h:66
uint8_t
enum AVStreamParseType need_parsing
Definition: avformat.h:811
unsigned version
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream ** streams
Definition: avformat.h:992
bitstream reader API header.
static int64_t duration
Definition: ffplay.c:294
int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
#define OGG_FLAG_EOS
Definition: oggdec.h:109
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
uint8_t segments[255]
Definition: oggdec.h:80
static int theora_packet(AVFormatContext *s, int idx)
Only parse headers, do not repack.
Definition: avformat.h:583
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
uint64_t granule
Definition: oggdec.h:70
int width
picture width / height.
unsigned int pstart
Definition: oggdec.h:65
struct ogg_stream * streams
Definition: oggdec.h:99
int segp
Definition: oggdec.h:79
AVDictionary * metadata
Definition: avformat.h:711
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
static int width
Definition: tests/utils.c:158
enum AVMediaType codec_type
unsigned int pduration
Definition: oggdec.h:68
int nsegs
Definition: oggdec.h:79
enum AVCodecID codec_id
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * private
Definition: oggdec.h:87
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
rational number numerator/denominator
Definition: rational.h:43
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
byte swapping routines
int64_t lastdts
Definition: oggdec.h:73
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:306
const int8_t * magic
Definition: oggdec.h:32
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:696
static int theora_header(AVFormatContext *s, int idx)
uint8_t * buf
Definition: oggdec.h:62
Main libavformat public API header.
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
Definition: avformat.h:689
int den
denominator
Definition: rational.h:45
Definition: oggdec.h:98
void * priv_data
Format private data.
Definition: avformat.h:964
const struct ogg_codec ff_theora_codec
#define gp
Definition: regdef.h:62
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190