Line | Branch | Exec | Source |
---|---|---|---|
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 | |||
30 | struct ogg_codec { | ||
31 | const int8_t *magic; | ||
32 | uint8_t magicsize; | ||
33 | const int8_t *name; | ||
34 | /** | ||
35 | * Attempt to process a packet as a header | ||
36 | * @return 1 if the packet was a valid header, | ||
37 | * 0 if the packet was not a header (was a data packet) | ||
38 | * -1 if an error occurred or for unsupported stream | ||
39 | */ | ||
40 | int (*header)(AVFormatContext *, int); | ||
41 | /** | ||
42 | * Attempt to process a packet as a data packet | ||
43 | * @return < 0 (AVERROR) code or -1 on error | ||
44 | * == 0 if the packet was a regular data packet. | ||
45 | * == 1 if the packet was a header from a chained bitstream. | ||
46 | * This will cause the packet to be skiped in calling code (ogg_packet() | ||
47 | */ | ||
48 | int (*packet)(AVFormatContext *, int); | ||
49 | /** | ||
50 | * Translate a granule into a timestamp. | ||
51 | * Will set dts if non-null and known. | ||
52 | * @return pts | ||
53 | */ | ||
54 | uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); | ||
55 | /** | ||
56 | * 1 if granule is the start time of the associated packet. | ||
57 | * 0 if granule is the end time of the associated packet. | ||
58 | */ | ||
59 | int granule_is_start; | ||
60 | /** | ||
61 | * Number of expected headers | ||
62 | */ | ||
63 | int nb_header; | ||
64 | void (*cleanup)(AVFormatContext *s, int idx); | ||
65 | }; | ||
66 | |||
67 | struct ogg_stream { | ||
68 | uint8_t *buf; | ||
69 | unsigned int bufsize; | ||
70 | unsigned int bufpos; | ||
71 | unsigned int pstart; | ||
72 | unsigned int psize; | ||
73 | unsigned int pflags; | ||
74 | unsigned int pduration; | ||
75 | uint32_t serial; | ||
76 | uint64_t granule; | ||
77 | uint64_t start_granule; | ||
78 | int64_t lastpts; | ||
79 | int64_t lastdts; | ||
80 | int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet | ||
81 | int64_t page_pos; ///< file offset of the current page | ||
82 | int flags; | ||
83 | const struct ogg_codec *codec; | ||
84 | int header; | ||
85 | int nsegs, segp; | ||
86 | uint8_t segments[255]; | ||
87 | int incomplete; ///< whether we're expecting a continuation in the next page | ||
88 | int page_end; ///< current packet is the last one completed in the page | ||
89 | int keyframe_seek; | ||
90 | int got_start; | ||
91 | int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise | ||
92 | int nb_header; ///< set to the number of parsed headers | ||
93 | int start_trimming; ///< set the number of packets to drop from the start | ||
94 | int end_trimming; ///< set the number of packets to drop from the end | ||
95 | uint8_t *new_metadata; | ||
96 | size_t new_metadata_size; | ||
97 | uint8_t *new_extradata; | ||
98 | size_t new_extradata_size; | ||
99 | void *private; | ||
100 | }; | ||
101 | |||
102 | struct ogg_state { | ||
103 | uint64_t pos; | ||
104 | int curidx; | ||
105 | struct ogg_state *next; | ||
106 | int nstreams; | ||
107 | struct ogg_stream streams[1]; | ||
108 | }; | ||
109 | |||
110 | struct ogg { | ||
111 | struct ogg_stream *streams; | ||
112 | int nstreams; | ||
113 | int headers; | ||
114 | int curidx; | ||
115 | int64_t page_pos; ///< file offset of the current page | ||
116 | struct ogg_state *state; | ||
117 | }; | ||
118 | |||
119 | #define OGG_FLAG_CONT 1 | ||
120 | #define OGG_FLAG_BOS 2 | ||
121 | #define OGG_FLAG_EOS 4 | ||
122 | |||
123 | #define OGG_NOGRANULE_VALUE (-1ull) | ||
124 | |||
125 | extern const struct ogg_codec ff_celt_codec; | ||
126 | extern const struct ogg_codec ff_dirac_codec; | ||
127 | extern const struct ogg_codec ff_flac_codec; | ||
128 | extern const struct ogg_codec ff_ogm_audio_codec; | ||
129 | extern const struct ogg_codec ff_ogm_old_codec; | ||
130 | extern const struct ogg_codec ff_ogm_text_codec; | ||
131 | extern const struct ogg_codec ff_ogm_video_codec; | ||
132 | extern const struct ogg_codec ff_old_dirac_codec; | ||
133 | extern const struct ogg_codec ff_old_flac_codec; | ||
134 | extern const struct ogg_codec ff_opus_codec; | ||
135 | extern const struct ogg_codec ff_skeleton_codec; | ||
136 | extern const struct ogg_codec ff_speex_codec; | ||
137 | extern const struct ogg_codec ff_theora_codec; | ||
138 | extern const struct ogg_codec ff_vorbis_codec; | ||
139 | extern const struct ogg_codec ff_vp8_codec; | ||
140 | |||
141 | /** | ||
142 | * Parse Vorbis comments | ||
143 | * | ||
144 | * @note The buffer will be temporarily modifed by this function, | ||
145 | * so it needs to be writable. Furthermore it must be padded | ||
146 | * by a single byte (not counted in size). | ||
147 | * All changes will have been reverted upon return. | ||
148 | */ | ||
149 | int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, | ||
150 | const uint8_t *buf, int size, int parse_picture); | ||
151 | |||
152 | /** | ||
153 | * Parse Vorbis comments and add metadata to an AVStream | ||
154 | * | ||
155 | * @note The buffer will be temporarily modifed by this function, | ||
156 | * so it needs to be writable. Furthermore it must be padded | ||
157 | * by a single byte (not counted in size). | ||
158 | * All changes will have been reverted upon return. | ||
159 | */ | ||
160 | int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, | ||
161 | const uint8_t *buf, int size); | ||
162 | |||
163 | static inline int | ||
164 | 1551 | ogg_find_stream (struct ogg * ogg, int serial) | |
165 | { | ||
166 | int i; | ||
167 | |||
168 |
2/2✓ Branch 0 taken 1521 times.
✓ Branch 1 taken 48 times.
|
1569 | for (i = 0; i < ogg->nstreams; i++) |
169 |
2/2✓ Branch 0 taken 1503 times.
✓ Branch 1 taken 18 times.
|
1521 | if (ogg->streams[i].serial == serial) |
170 | 1503 | return i; | |
171 | |||
172 | 48 | return -1; | |
173 | } | ||
174 | |||
175 | static inline uint64_t | ||
176 | 987 | ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) | |
177 | { | ||
178 | 987 | struct ogg *ogg = s->priv_data; | |
179 | 987 | struct ogg_stream *os = ogg->streams + i; | |
180 | 987 | uint64_t pts = AV_NOPTS_VALUE; | |
181 | |||
182 |
3/4✓ Branch 0 taken 987 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 897 times.
|
987 | if(os->codec && os->codec->gptopts){ |
183 | 90 | pts = os->codec->gptopts(s, i, gp, dts); | |
184 | } else { | ||
185 | 897 | pts = gp; | |
186 |
2/2✓ Branch 0 taken 517 times.
✓ Branch 1 taken 380 times.
|
897 | if (dts) |
187 | 517 | *dts = pts; | |
188 | } | ||
189 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 987 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
987 | if (pts > INT64_MAX && pts != AV_NOPTS_VALUE) { |
190 | // The return type is unsigned, we thus cannot return negative pts | ||
191 | ✗ | av_log(s, AV_LOG_ERROR, "invalid pts %"PRId64"\n", pts); | |
192 | ✗ | pts = AV_NOPTS_VALUE; | |
193 | } | ||
194 | |||
195 | 987 | return pts; | |
196 | } | ||
197 | |||
198 | #endif /* AVFORMAT_OGGDEC_H */ | ||
199 |