FFmpeg
Loading...
Searching...
No Matches
theora.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>
27#include "libavutil/mem.h"
28#include "libavcodec/get_bits.h"
33
34typedef struct TheoraParams {
36 int gpmask;
37 unsigned version;
39
40static int theora_header(AVFormatContext *s, int idx)
41{
42 struct ogg *ogg = s->priv_data;
43 struct ogg_stream *os = ogg->streams + idx;
44 AVStream *st = s->streams[idx];
45 TheoraParams *thp = os->private;
46 int cds = st->codecpar->extradata_size + os->psize + 2;
47 int err;
48 uint8_t *cdp;
49
50 if (!(os->buf[os->pstart] & 0x80))
51 return 0;
52
53 if (!thp) {
54 thp = av_mallocz(sizeof(*thp));
55 if (!thp)
56 return AVERROR(ENOMEM);
57 os->private = thp;
58 }
59
60 switch (os->buf[os->pstart]) {
61 case 0x80: {
63 AVRational timebase;
64
65 init_get_bits(&gb, os->buf + os->pstart, os->psize * 8);
66
67 /* 0x80"theora" */
68 skip_bits_long(&gb, 7 * 8);
69
70 thp->version = get_bits(&gb, 24);
71 if (thp->version < 0x030100) {
73 "Too old or unsupported Theora (%x)\n", thp->version);
74 return AVERROR(ENOSYS);
75 }
76
77 st->codecpar->width = get_bits(&gb, 16) << 4;
78 st->codecpar->height = get_bits(&gb, 16) << 4;
79
80 if (thp->version >= 0x030400)
81 skip_bits(&gb, 100);
82
83 if (thp->version >= 0x030200) {
84 int width = get_bits(&gb, 24);
85 int height = get_bits(&gb, 24);
86 if (width <= st->codecpar->width && width > st->codecpar->width - 16 &&
87 height <= st->codecpar->height && height > st->codecpar->height - 16) {
88 st->codecpar->width = width;
89 st->codecpar->height = height;
90 }
91
92 skip_bits(&gb, 16);
93 }
94
95 timebase.den = get_bits_long(&gb, 32);
96 timebase.num = get_bits_long(&gb, 32);
97 if (!(timebase.num > 0 && timebase.den > 0)) {
98 av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
99 timebase.num = 1;
100 timebase.den = 25;
101 }
102 avpriv_set_pts_info(st, 64, timebase.num, timebase.den);
103
104 st->sample_aspect_ratio.num = get_bits(&gb, 24);
105 st->sample_aspect_ratio.den = get_bits(&gb, 24);
106
107 if (thp->version >= 0x030200)
108 skip_bits_long(&gb, 38);
109 if (thp->version >= 0x304000)
110 skip_bits(&gb, 2);
111
112 thp->gpshift = get_bits(&gb, 5);
113 thp->gpmask = (1U << thp->gpshift) - 1;
114
118 }
119 break;
120 case 0x81:
121 ff_vorbis_comment_read_stream(s, st, os->buf + os->pstart + 7, os->psize - 7);
123 case 0x82:
124 if (!thp->version)
125 return AVERROR_INVALIDDATA;
126 break;
127 default:
128 av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
129 return AVERROR_INVALIDDATA;
130 }
131
132 if ((err = av_reallocp(&st->codecpar->extradata,
133 cds + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
134 st->codecpar->extradata_size = 0;
135 return err;
136 }
137 memset(st->codecpar->extradata + cds, 0, AV_INPUT_BUFFER_PADDING_SIZE);
138
139 cdp = st->codecpar->extradata + st->codecpar->extradata_size;
140 *cdp++ = os->psize >> 8;
141 *cdp++ = os->psize & 0xff;
142 memcpy(cdp, os->buf + os->pstart, os->psize);
143 st->codecpar->extradata_size = cds;
144
145 return 1;
146}
147
148static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
149 int64_t *dts)
150{
151 struct ogg *ogg = ctx->priv_data;
152 struct ogg_stream *os = ogg->streams + idx;
153 TheoraParams *thp = os->private;
154 uint64_t iframe, pframe;
155
156 if (!thp)
157 return AV_NOPTS_VALUE;
158
159 iframe = gp >> thp->gpshift;
160 pframe = gp & thp->gpmask;
161
162 if (thp->version < 0x030201)
163 iframe++;
164
165 if (!pframe)
166 os->pflags |= AV_PKT_FLAG_KEY;
167
168 if (dts)
169 *dts = iframe + pframe;
170
171 return iframe + pframe;
172}
173
174static int theora_packet(AVFormatContext *s, int idx)
175{
176 struct ogg *ogg = s->priv_data;
177 struct ogg_stream *os = ogg->streams + idx;
178 int duration;
179
180 /* first packet handling
181 here we parse the duration of each packet in the first page and compare
182 the total duration to the page granule to find the encoder delay and
183 set the first timestamp */
184
185 if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
186 int seg;
187 int64_t pts;
188
189 duration = 1;
190 for (seg = os->segp; seg < os->nsegs; seg++) {
191 if (os->segments[seg] < 255)
192 duration ++;
193 }
194
195 pts = theora_gptopts(s, idx, os->granule, NULL);
196 if (pts != AV_NOPTS_VALUE)
198 os->lastpts = os->lastdts = pts;
199 if(s->streams[idx]->start_time == AV_NOPTS_VALUE && os->lastpts != AV_NOPTS_VALUE) {
200 s->streams[idx]->start_time = os->lastpts;
201 if (s->streams[idx]->duration > 0)
202 s->streams[idx]->duration = av_sat_sub64(s->streams[idx]->duration, s->streams[idx]->start_time);
203 }
204 }
205
206 /* parse packet duration */
207 if (os->psize > 0) {
208 os->pduration = 1;
209 }
210
211 return 0;
212}
213
215 .magic = "\200theora",
216 .magicsize = 7,
217 .header = theora_header,
218 .packet = theora_packet,
219 .gptopts = theora_gptopts,
220 .nb_header = 3,
221};
static AVFormatContext * ctx
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:865
Main libavformat public API header.
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:614
#define s(width, name)
Definition cbs_vp9.c:198
int ff_vorbis_comment_read_stream(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
Definition reader.c:73
#define av_sat_sub64
Definition common.h:142
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static int64_t duration
Definition ffplay.c:359
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition get_bits.h:424
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition get_bits.h:280
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition get_bits.h:517
@ AV_CODEC_ID_THEORA
Definition codec_id.h:80
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:657
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
static av_always_inline FFStream * ffstream(AVStream *st)
Definition internal.h:390
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
#define OGG_FLAG_EOS
Definition mapping.h:123
const struct ogg_codec ff_theora_codec
Definition theora.c:214
Memory handling functions.
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int width
The width of the video frame in pixels.
Definition codec_par.h:143
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
Format I/O context.
Definition avformat.h:1401
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
enum AVStreamParseType need_parsing
Definition internal.h:346
Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi.
Definition theora.c:34
int gpmask
Definition theora.c:36
int gpshift
Definition theora.c:35
unsigned version
Definition theora.c:37
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition mapping.h:30
unsigned int pduration
Definition mapping.h:74
unsigned int pflags
Definition mapping.h:73
int nsegs
Definition mapping.h:85
uint8_t segments[255]
Definition mapping.h:86
uint64_t granule
Definition mapping.h:76
int64_t lastdts
Definition mapping.h:79
unsigned int pstart
Definition mapping.h:71
unsigned int psize
Definition mapping.h:72
void * private
Definition mapping.h:101
uint8_t * buf
Definition mapping.h:68
int64_t lastpts
Definition mapping.h:78
int segp
Definition mapping.h:85
int flags
Definition mapping.h:82
Definition mapping.h:112
struct ogg_stream * streams
Definition mapping.h:113
#define av_mallocz(s)
#define av_log(a,...)
#define height
Definition dsp.h:99
#define width
Definition dsp.h:99
static int theora_packet(AVFormatContext *s, int idx)
Definition theora.c:174
static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
Definition theora.c:148
static int theora_header(AVFormatContext *s, int idx)
Definition theora.c:40
static int64_t pts