Libav
oggparsetheora.c
Go to the documentation of this file.
1 
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) {
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 
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 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
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
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:129
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.
Definition: utils.c:2821
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:199
const struct ogg_codec * codec
Definition: oggdec.h:77
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:718
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:769
int num
numerator
Definition: rational.h:44
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1164
Format I/O context.
Definition: avformat.h:922
unsigned int psize
Definition: oggdec.h:66
uint8_t
enum AVStreamParseType need_parsing
Definition: avformat.h:867
int av_reallocp(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:140
bitstream reader API header.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1019
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
void * priv_data
Format private data.
Definition: avformat.h:950
#define AVERROR(e)
Definition: error.h:43
int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:531
int width
picture width / height.
Definition: avcodec.h:1224
unsigned int pstart
Definition: oggdec.h:65
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:990
struct ogg_stream * streams
Definition: oggdec.h:97
Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi.
Stream structure.
Definition: avformat.h:699
static int width
Definition: utils.c:156
enum AVMediaType codec_type
Definition: avcodec.h:1058
enum AVCodecID codec_id
Definition: avcodec.h:1067
int extradata_size
Definition: avcodec.h:1165
void * private
Definition: oggdec.h:85
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:263
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:375
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:304
const int8_t * magic
Definition: oggdec.h:32
int height
Definition: gxfenc.c:72
static int theora_header(AVFormatContext *s, int idx)
uint8_t * buf
Definition: oggdec.h:62
unsigned version
Main libavformat public API header.
int den
denominator
Definition: rational.h:45
Definition: oggdec.h:96
const struct ogg_codec ff_theora_codec
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:228
void * av_mallocz(size_t size) av_malloc_attrib 1(1)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
Only parse headers, do not repack.
Definition: avformat.h:654