ffmpeg / libavformat / oggparsetheora.c @ 2912e87a
History | View | Annotate | Download (4.92 KB)
1 | 1ed923ea | Måns Rullgård | /**
|
---|---|---|---|
2 | 571fa531 | Alex Beregszaszi | Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi
|
3 | 1ed923ea | Måns Rullgård | |
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 | 245976da | Diego Biurrun | #include "libavutil/bswap.h" |
27 | 9106a698 | Stefano Sabatini | #include "libavcodec/get_bits.h" |
28 | 1ed923ea | Måns Rullgård | #include "avformat.h" |
29 | a0ddef24 | Diego Biurrun | #include "oggdec.h" |
30 | 1ed923ea | Måns Rullgård | |
31 | 77be08ee | Måns Rullgård | struct theora_params {
|
32 | 1ed923ea | Måns Rullgård | int gpshift;
|
33 | int gpmask;
|
||
34 | e3b07e1a | Måns Rullgård | unsigned version;
|
35 | 77be08ee | Måns Rullgård | }; |
36 | 1ed923ea | Måns Rullgård | |
37 | static int |
||
38 | theora_header (AVFormatContext * s, int idx)
|
||
39 | { |
||
40 | 77be08ee | Måns Rullgård | struct ogg *ogg = s->priv_data;
|
41 | struct ogg_stream *os = ogg->streams + idx;
|
||
42 | 1ed923ea | Måns Rullgård | AVStream *st = s->streams[idx]; |
43 | 77be08ee | Måns Rullgård | struct theora_params *thp = os->private;
|
44 | 01f4895c | Michael Niedermayer | int cds = st->codec->extradata_size + os->psize + 2; |
45 | 1ed923ea | Måns Rullgård | uint8_t *cdp; |
46 | |||
47 | 5b558574 | Måns Rullgård | if(!(os->buf[os->pstart] & 0x80)) |
48 | 1ed923ea | Måns Rullgård | return 0; |
49 | |||
50 | if(!thp){
|
||
51 | bb270c08 | Diego Biurrun | thp = av_mallocz(sizeof(*thp));
|
52 | os->private = thp; |
||
53 | 1ed923ea | Måns Rullgård | } |
54 | |||
55 | if (os->buf[os->pstart] == 0x80) { |
||
56 | GetBitContext gb; |
||
57 | c0f716b8 | Aurelien Jacobs | int width, height;
|
58 | 571fa531 | Alex Beregszaszi | |
59 | 1ed923ea | Måns Rullgård | init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
|
60 | |||
61 | 0a8dedc9 | David Conrad | skip_bits_long(&gb, 7*8); /* 0x80"theora" */ |
62 | 571fa531 | Alex Beregszaszi | |
63 | e3b07e1a | Måns Rullgård | thp->version = get_bits_long(&gb, 24);
|
64 | if (thp->version < 0x030100) |
||
65 | 571fa531 | Alex Beregszaszi | { |
66 | av_log(s, AV_LOG_ERROR, |
||
67 | e3b07e1a | Måns Rullgård | "Too old or unsupported Theora (%x)\n", thp->version);
|
68 | 5b558574 | Måns Rullgård | return -1; |
69 | 571fa531 | Alex Beregszaszi | } |
70 | 5b558574 | Måns Rullgård | |
71 | c0f716b8 | Aurelien Jacobs | width = get_bits(&gb, 16) << 4; |
72 | height = get_bits(&gb, 16) << 4; |
||
73 | avcodec_set_dimensions(st->codec, width, height); |
||
74 | 1ed923ea | Måns Rullgård | |
75 | e3b07e1a | Måns Rullgård | if (thp->version >= 0x030400) |
76 | c0f716b8 | Aurelien Jacobs | skip_bits(&gb, 100);
|
77 | |||
78 | e3b07e1a | Måns Rullgård | if (thp->version >= 0x030200) { |
79 | a0ce2d1b | David Conrad | width = get_bits_long(&gb, 24);
|
80 | height = get_bits_long(&gb, 24);
|
||
81 | if ( width <= st->codec->width && width > st->codec->width-16 |
||
82 | && height <= st->codec->height && height > st->codec->height-16)
|
||
83 | avcodec_set_dimensions(st->codec, width, height); |
||
84 | c0f716b8 | Aurelien Jacobs | |
85 | skip_bits(&gb, 16);
|
||
86 | 277e3e53 | David Conrad | } |
87 | b997b67c | Aurelien Jacobs | st->codec->time_base.den = get_bits_long(&gb, 32);
|
88 | st->codec->time_base.num = get_bits_long(&gb, 32);
|
||
89 | 11d058b7 | Reimar Döffinger | if (!(st->codec->time_base.num > 0 && st->codec->time_base.den > 0)) { |
90 | av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n");
|
||
91 | st->codec->time_base.num = 1;
|
||
92 | st->codec->time_base.den = 25;
|
||
93 | } |
||
94 | a351110e | Reimar Döffinger | av_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
|
95 | 115329f1 | Diego Biurrun | |
96 | 59729451 | Aurelien Jacobs | st->sample_aspect_ratio.num = get_bits_long(&gb, 24);
|
97 | st->sample_aspect_ratio.den = get_bits_long(&gb, 24);
|
||
98 | 1ed923ea | Måns Rullgård | |
99 | e3b07e1a | Måns Rullgård | if (thp->version >= 0x030200) |
100 | 0a8dedc9 | David Conrad | skip_bits_long(&gb, 38);
|
101 | e3b07e1a | Måns Rullgård | if (thp->version >= 0x304000) |
102 | 571fa531 | Alex Beregszaszi | skip_bits(&gb, 2);
|
103 | |||
104 | 1ed923ea | Måns Rullgård | thp->gpshift = get_bits(&gb, 5);
|
105 | bb270c08 | Diego Biurrun | thp->gpmask = (1 << thp->gpshift) - 1; |
106 | 1ed923ea | Måns Rullgård | |
107 | 72415b2a | Stefano Sabatini | st->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
108 | 01f4895c | Michael Niedermayer | st->codec->codec_id = CODEC_ID_THEORA; |
109 | 8b6bdb6c | David Conrad | st->need_parsing = AVSTREAM_PARSE_HEADERS; |
110 | 1ed923ea | Måns Rullgård | |
111 | } else if (os->buf[os->pstart] == 0x83) { |
||
112 | b53cde48 | David Conrad | ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8); |
113 | 1ed923ea | Måns Rullgård | } |
114 | |||
115 | 12d7c079 | David Conrad | st->codec->extradata = av_realloc (st->codec->extradata, |
116 | cds + FF_INPUT_BUFFER_PADDING_SIZE); |
||
117 | 01f4895c | Michael Niedermayer | cdp = st->codec->extradata + st->codec->extradata_size; |
118 | 1ed923ea | Måns Rullgård | *cdp++ = os->psize >> 8;
|
119 | *cdp++ = os->psize & 0xff;
|
||
120 | memcpy (cdp, os->buf + os->pstart, os->psize); |
||
121 | 01f4895c | Michael Niedermayer | st->codec->extradata_size = cds; |
122 | 1ed923ea | Måns Rullgård | |
123 | 5b558574 | Måns Rullgård | return 1; |
124 | 1ed923ea | Måns Rullgård | } |
125 | |||
126 | static uint64_t
|
||
127 | 2d4970d8 | David Conrad | theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts)
|
128 | 1ed923ea | Måns Rullgård | { |
129 | 77be08ee | Måns Rullgård | struct ogg *ogg = ctx->priv_data;
|
130 | struct ogg_stream *os = ogg->streams + idx;
|
||
131 | struct theora_params *thp = os->private;
|
||
132 | 1ed923ea | Måns Rullgård | uint64_t iframe = gp >> thp->gpshift; |
133 | uint64_t pframe = gp & thp->gpmask; |
||
134 | |||
135 | e3b07e1a | Måns Rullgård | if (thp->version < 0x030201) |
136 | iframe++; |
||
137 | |||
138 | e1a794b2 | Måns Rullgård | if(!pframe)
|
139 | cc947f04 | Jean-Daniel Dupas | os->pflags |= AV_PKT_FLAG_KEY; |
140 | e1a794b2 | Måns Rullgård | |
141 | 2d4970d8 | David Conrad | if (dts)
|
142 | *dts = iframe + pframe; |
||
143 | |||
144 | 3644cb8f | Måns Rullgård | return iframe + pframe;
|
145 | 1ed923ea | Måns Rullgård | } |
146 | |||
147 | 77be08ee | Måns Rullgård | const struct ogg_codec ff_theora_codec = { |
148 | 1ed923ea | Måns Rullgård | .magic = "\200theora",
|
149 | .magicsize = 7,
|
||
150 | .header = theora_header, |
||
151 | .gptopts = theora_gptopts |
||
152 | }; |