755
|
1 /**
|
|
2 Copyright (C) 2005 Matthieu CASTET
|
|
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 "avformat.h"
|
|
27 #include "bitstream.h"
|
|
28 #include "bswap.h"
|
|
29 #include "ogg2.h"
|
|
30
|
|
31 typedef struct theora_params {
|
|
32 int gpshift;
|
|
33 int gpmask;
|
|
34 } theora_params_t;
|
|
35
|
|
36 static int
|
|
37 theora_header (AVFormatContext * s, int idx)
|
|
38 {
|
|
39 ogg_t *ogg = s->priv_data;
|
|
40 ogg_stream_t *os = ogg->streams + idx;
|
|
41 AVStream *st = s->streams[idx];
|
|
42 theora_params_t *thp = os->private;
|
|
43 int cds = st->codec.extradata_size + os->psize + 2;
|
|
44 uint8_t *cdp;
|
|
45
|
|
46 if (os->seq > 2)
|
|
47 return 0;
|
|
48
|
|
49 if(!thp){
|
|
50 thp = av_mallocz(sizeof(*thp));
|
|
51 os->private = thp;
|
|
52 }
|
|
53
|
|
54 if (os->buf[os->pstart] == 0x80) {
|
|
55 GetBitContext gb;
|
|
56 init_get_bits(&gb, os->buf + os->pstart, os->psize*8);
|
|
57
|
|
58 skip_bits(&gb, 7*8); /* 0x80"theora" */
|
|
59 skip_bits(&gb, 3*8);
|
|
60
|
|
61 st->codec.width = get_bits(&gb, 16) << 4;
|
|
62 st->codec.height = get_bits(&gb, 16) << 4;
|
|
63
|
|
64 skip_bits(&gb, 64);
|
|
65 st->codec.time_base.den = get_bits(&gb, 32);
|
|
66 st->codec.time_base.num = get_bits(&gb, 32);
|
|
67
|
|
68 st->codec.sample_aspect_ratio.num = get_bits(&gb, 24);
|
|
69 st->codec.sample_aspect_ratio.den = get_bits(&gb, 24);
|
|
70
|
|
71 skip_bits(&gb, 38);
|
|
72 thp->gpshift = get_bits(&gb, 5);
|
|
73 thp->gpmask = (1 << thp->gpshift) - 1;
|
|
74
|
|
75 st->codec.codec_type = CODEC_TYPE_VIDEO;
|
|
76 st->codec.codec_id = CODEC_ID_THEORA;
|
|
77
|
|
78 } else if (os->buf[os->pstart] == 0x83) {
|
|
79 vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8);
|
|
80 }
|
|
81
|
|
82 st->codec.extradata = av_realloc (st->codec.extradata, cds);
|
|
83 cdp = st->codec.extradata + st->codec.extradata_size;
|
|
84 *cdp++ = os->psize >> 8;
|
|
85 *cdp++ = os->psize & 0xff;
|
|
86 memcpy (cdp, os->buf + os->pstart, os->psize);
|
|
87 st->codec.extradata_size = cds;
|
|
88
|
|
89
|
|
90 return os->seq < 3;
|
|
91 }
|
|
92
|
|
93 static uint64_t
|
|
94 theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp)
|
|
95 {
|
|
96 AVStream *st = ctx->streams[idx];
|
|
97 ogg_t *ogg = ctx->priv_data;
|
|
98 ogg_stream_t *os = ogg->streams + idx;
|
|
99 theora_params_t *thp = os->private;
|
|
100 uint64_t iframe = gp >> thp->gpshift;
|
|
101 uint64_t pframe = gp & thp->gpmask;
|
|
102
|
|
103 return (iframe + pframe) * AV_TIME_BASE * st->codec.time_base.num /
|
|
104 st->codec.time_base.den;
|
|
105 }
|
|
106
|
|
107 ogg_codec_t theora_codec = {
|
|
108 .magic = "\200theora",
|
|
109 .magicsize = 7,
|
|
110 .header = theora_header,
|
|
111 .gptopts = theora_gptopts
|
|
112 };
|