FFmpeg
Loading...
Searching...
No Matches
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>
27#include "libavutil/mem.h"
28#include "libavcodec/get_bits.h"
29#include "avformat.h"
30#include "internal.h"
31#include "oggdec.h"
32
33typedef struct TheoraParams {
35 int gpmask;
36 unsigned version;
38
39static int theora_header(AVFormatContext *s, int idx)
40{
41 struct ogg *ogg = s->priv_data;
42 struct ogg_stream *os = ogg->streams + idx;
43 AVStream *st = s->streams[idx];
44 TheoraParams *thp = os->private;
45 int cds = st->codecpar->extradata_size + os->psize + 2;
46 int err;
47 uint8_t *cdp;
48
49 if (!(os->buf[os->pstart] & 0x80))
50 return 0;
51
52 if (!thp) {
53 thp = av_mallocz(sizeof(*thp));
54 if (!thp)
55 return AVERROR(ENOMEM);
56 os->private = thp;
57 }
58
59 switch (os->buf[os->pstart]) {
60 case 0x80: {
62 AVRational timebase;
63
64 init_get_bits(&gb, os->buf + os->pstart, os->psize * 8);
65
66 /* 0x80"theora" */
67 skip_bits_long(&gb, 7 * 8);
68
69 thp->version = get_bits(&gb, 24);
70 if (thp->version < 0x030100) {
72 "Too old or unsupported Theora (%x)\n", thp->version);
73 return AVERROR(ENOSYS);
74 }
75
76 st->codecpar->width = get_bits(&gb, 16) << 4;
77 st->codecpar->height = get_bits(&gb, 16) << 4;
78
79 if (thp->version >= 0x030400)
80 skip_bits(&gb, 100);
81
82 if (thp->version >= 0x030200) {
83 int width = get_bits(&gb, 24);
84 int height = get_bits(&gb, 24);
85 if (width <= st->codecpar->width && width > st->codecpar->width - 16 &&
86 height <= st->codecpar->height && height > st->codecpar->height - 16) {
87 st->codecpar->width = width;
88 st->codecpar->height = height;
89 }
90
91 skip_bits(&gb, 16);
92 }
93
94 timebase.den = get_bits_long(&gb, 32);
95 timebase.num = get_bits_long(&gb, 32);
96 if (!(timebase.num > 0 && timebase.den > 0)) {
97 av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
98 timebase.num = 1;
99 timebase.den = 25;
100 }
101 avpriv_set_pts_info(st, 64, timebase.num, timebase.den);
102
103 st->sample_aspect_ratio.num = get_bits(&gb, 24);
104 st->sample_aspect_ratio.den = get_bits(&gb, 24);
105
106 if (thp->version >= 0x030200)
107 skip_bits_long(&gb, 38);
108 if (thp->version >= 0x304000)
109 skip_bits(&gb, 2);
110
111 thp->gpshift = get_bits(&gb, 5);
112 thp->gpmask = (1U << thp->gpshift) - 1;
113
117 }
118 break;
119 case 0x81:
120 ff_vorbis_stream_comment(s, st, os->buf + os->pstart + 7, os->psize - 7);
122 case 0x82:
123 if (!thp->version)
124 return AVERROR_INVALIDDATA;
125 break;
126 default:
127 av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
128 return AVERROR_INVALIDDATA;
129 }
130
131 if ((err = av_reallocp(&st->codecpar->extradata,
132 cds + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
133 st->codecpar->extradata_size = 0;
134 return err;
135 }
136 memset(st->codecpar->extradata + cds, 0, AV_INPUT_BUFFER_PADDING_SIZE);
137
138 cdp = st->codecpar->extradata + st->codecpar->extradata_size;
139 *cdp++ = os->psize >> 8;
140 *cdp++ = os->psize & 0xff;
141 memcpy(cdp, os->buf + os->pstart, os->psize);
142 st->codecpar->extradata_size = cds;
143
144 return 1;
145}
146
147static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp,
148 int64_t *dts)
149{
150 struct ogg *ogg = ctx->priv_data;
151 struct ogg_stream *os = ogg->streams + idx;
152 TheoraParams *thp = os->private;
153 uint64_t iframe, pframe;
154
155 if (!thp)
156 return AV_NOPTS_VALUE;
157
158 iframe = gp >> thp->gpshift;
159 pframe = gp & thp->gpmask;
160
161 if (thp->version < 0x030201)
162 iframe++;
163
164 if (!pframe)
165 os->pflags |= AV_PKT_FLAG_KEY;
166
167 if (dts)
168 *dts = iframe + pframe;
169
170 return iframe + pframe;
171}
172
173static int theora_packet(AVFormatContext *s, int idx)
174{
175 struct ogg *ogg = s->priv_data;
176 struct ogg_stream *os = ogg->streams + idx;
177 int duration;
178
179 /* first packet handling
180 here we parse the duration of each packet in the first page and compare
181 the total duration to the page granule to find the encoder delay and
182 set the first timestamp */
183
184 if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
185 int seg;
186 int64_t pts;
187
188 duration = 1;
189 for (seg = os->segp; seg < os->nsegs; seg++) {
190 if (os->segments[seg] < 255)
191 duration ++;
192 }
193
194 pts = theora_gptopts(s, idx, os->granule, NULL);
195 if (pts != AV_NOPTS_VALUE)
197 os->lastpts = os->lastdts = pts;
198 if(s->streams[idx]->start_time == AV_NOPTS_VALUE && os->lastpts != AV_NOPTS_VALUE) {
199 s->streams[idx]->start_time = os->lastpts;
200 if (s->streams[idx]->duration > 0)
201 s->streams[idx]->duration = av_sat_sub64(s->streams[idx]->duration, s->streams[idx]->start_time);
202 }
203 }
204
205 /* parse packet duration */
206 if (os->psize > 0) {
207 os->pduration = 1;
208 }
209
210 return 0;
211}
212
214 .magic = "\200theora",
215 .magicsize = 7,
216 .header = theora_header,
217 .packet = theora_packet,
218 .gptopts = theora_gptopts,
219 .nb_header = 3,
220};
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:834
Main libavformat public API header.
@ AVSTREAM_PARSE_HEADERS
Only parse headers, do not repack.
Definition avformat.h:612
#define s(width, name)
Definition cbs_vp9.c:198
#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:330
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:650
#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:188
@ 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:365
Macro definitions for various function/variable attributes.
#define av_fallthrough
Definition attributes.h:67
Memory handling functions.
int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
#define OGG_FLAG_EOS
Definition oggdec.h:123
const struct ogg_codec ff_theora_codec
static int theora_packet(AVFormatContext *s, int idx)
static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
static int theora_header(AVFormatContext *s, int idx)
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:1333
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:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:844
enum AVStreamParseType need_parsing
Definition internal.h:321
Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi.
unsigned version
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition oggdec.h:30
unsigned int pduration
Definition oggdec.h:74
unsigned int pflags
Definition oggdec.h:73
int nsegs
Definition oggdec.h:85
uint8_t segments[255]
Definition oggdec.h:86
uint64_t granule
Definition oggdec.h:76
int64_t lastdts
Definition oggdec.h:79
unsigned int pstart
Definition oggdec.h:71
unsigned int psize
Definition oggdec.h:72
void * private
Definition oggdec.h:101
uint8_t * buf
Definition oggdec.h:68
int64_t lastpts
Definition oggdec.h:78
int segp
Definition oggdec.h:85
int flags
Definition oggdec.h:82
Definition oggdec.h:112
struct ogg_stream * streams
Definition oggdec.h:113
#define av_mallocz(s)
#define av_log(a,...)
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static int64_t pts