blob: 4a2b6ddee8ff02aaeb489467a6f6fe319606eacf
1 | /** |
2 | Copyright (C) 2005 Michael Ahlberg, Måns Rullgård |
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 | #ifndef AVFORMAT_OGGDEC_H |
26 | #define AVFORMAT_OGGDEC_H |
27 | |
28 | #include "avformat.h" |
29 | #include "metadata.h" |
30 | |
31 | struct ogg_codec { |
32 | const int8_t *magic; |
33 | uint8_t magicsize; |
34 | const int8_t *name; |
35 | /** |
36 | * Attempt to process a packet as a header |
37 | * @return 1 if the packet was a valid header, |
38 | * 0 if the packet was not a header (was a data packet) |
39 | * -1 if an error occurred or for unsupported stream |
40 | */ |
41 | int (*header)(AVFormatContext *, int); |
42 | int (*packet)(AVFormatContext *, int); |
43 | /** |
44 | * Translate a granule into a timestamp. |
45 | * Will set dts if non-null and known. |
46 | * @return pts |
47 | */ |
48 | uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); |
49 | /** |
50 | * 1 if granule is the start time of the associated packet. |
51 | * 0 if granule is the end time of the associated packet. |
52 | */ |
53 | int granule_is_start; |
54 | /** |
55 | * Number of expected headers |
56 | */ |
57 | int nb_header; |
58 | void (*cleanup)(AVFormatContext *s, int idx); |
59 | }; |
60 | |
61 | struct ogg_stream { |
62 | uint8_t *buf; |
63 | unsigned int bufsize; |
64 | unsigned int bufpos; |
65 | unsigned int pstart; |
66 | unsigned int psize; |
67 | unsigned int pflags; |
68 | unsigned int pduration; |
69 | uint32_t serial; |
70 | uint64_t granule; |
71 | uint64_t start_granule; |
72 | int64_t lastpts; |
73 | int64_t lastdts; |
74 | int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet |
75 | int64_t page_pos; ///< file offset of the current page |
76 | int flags; |
77 | const struct ogg_codec *codec; |
78 | int header; |
79 | int nsegs, segp; |
80 | uint8_t segments[255]; |
81 | int incomplete; ///< whether we're expecting a continuation in the next page |
82 | int page_end; ///< current packet is the last one completed in the page |
83 | int keyframe_seek; |
84 | int got_start; |
85 | int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise |
86 | int nb_header; ///< set to the number of parsed headers |
87 | int end_trimming; ///< set the number of packets to drop from the end |
88 | uint8_t *new_metadata; |
89 | unsigned int new_metadata_size; |
90 | void *private; |
91 | }; |
92 | |
93 | struct ogg_state { |
94 | uint64_t pos; |
95 | int curidx; |
96 | struct ogg_state *next; |
97 | int nstreams; |
98 | struct ogg_stream streams[1]; |
99 | }; |
100 | |
101 | struct ogg { |
102 | struct ogg_stream *streams; |
103 | int nstreams; |
104 | int headers; |
105 | int curidx; |
106 | int64_t page_pos; ///< file offset of the current page |
107 | struct ogg_state *state; |
108 | }; |
109 | |
110 | #define OGG_FLAG_CONT 1 |
111 | #define OGG_FLAG_BOS 2 |
112 | #define OGG_FLAG_EOS 4 |
113 | |
114 | #define OGG_NOGRANULE_VALUE (-1ull) |
115 | |
116 | extern const struct ogg_codec ff_celt_codec; |
117 | extern const struct ogg_codec ff_daala_codec; |
118 | extern const struct ogg_codec ff_dirac_codec; |
119 | extern const struct ogg_codec ff_flac_codec; |
120 | extern const struct ogg_codec ff_ogm_audio_codec; |
121 | extern const struct ogg_codec ff_ogm_old_codec; |
122 | extern const struct ogg_codec ff_ogm_text_codec; |
123 | extern const struct ogg_codec ff_ogm_video_codec; |
124 | extern const struct ogg_codec ff_old_dirac_codec; |
125 | extern const struct ogg_codec ff_old_flac_codec; |
126 | extern const struct ogg_codec ff_opus_codec; |
127 | extern const struct ogg_codec ff_skeleton_codec; |
128 | extern const struct ogg_codec ff_speex_codec; |
129 | extern const struct ogg_codec ff_theora_codec; |
130 | extern const struct ogg_codec ff_vorbis_codec; |
131 | extern const struct ogg_codec ff_vp8_codec; |
132 | |
133 | int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, |
134 | const uint8_t *buf, int size, int parse_picture); |
135 | |
136 | int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, |
137 | const uint8_t *buf, int size); |
138 | |
139 | static inline int |
140 | ogg_find_stream (struct ogg * ogg, int serial) |
141 | { |
142 | int i; |
143 | |
144 | for (i = 0; i < ogg->nstreams; i++) |
145 | if (ogg->streams[i].serial == serial) |
146 | return i; |
147 | |
148 | return -1; |
149 | } |
150 | |
151 | static inline uint64_t |
152 | ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) |
153 | { |
154 | struct ogg *ogg = s->priv_data; |
155 | struct ogg_stream *os = ogg->streams + i; |
156 | uint64_t pts = AV_NOPTS_VALUE; |
157 | |
158 | if(os->codec && os->codec->gptopts){ |
159 | pts = os->codec->gptopts(s, i, gp, dts); |
160 | } else { |
161 | pts = gp; |
162 | if (dts) |
163 | *dts = pts; |
164 | } |
165 | if (pts > INT64_MAX && pts != AV_NOPTS_VALUE) { |
166 | // The return type is unsigned, we thus cannot return negative pts |
167 | av_log(s, AV_LOG_ERROR, "invalid pts %"PRId64"\n", pts); |
168 | pts = AV_NOPTS_VALUE; |
169 | } |
170 | |
171 | return pts; |
172 | } |
173 | |
174 | #endif /* AVFORMAT_OGGDEC_H */ |
175 |