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 | int (*packet)(AVFormatContext *, int); | ||
42 | /** | ||
43 | * Translate a granule into a timestamp. | ||
44 | * Will set dts if non-null and known. | ||
45 | * @return pts | ||
46 | */ | ||
47 | uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); | ||
48 | /** | ||
49 | * 1 if granule is the start time of the associated packet. | ||
50 | * 0 if granule is the end time of the associated packet. | ||
51 | */ | ||
52 | int granule_is_start; | ||
53 | /** | ||
54 | * Number of expected headers | ||
55 | */ | ||
56 | int nb_header; | ||
57 | void (*cleanup)(AVFormatContext *s, int idx); | ||
58 | }; | ||
59 | |||
60 | struct ogg_stream { | ||
61 | uint8_t *buf; | ||
62 | unsigned int bufsize; | ||
63 | unsigned int bufpos; | ||
64 | unsigned int pstart; | ||
65 | unsigned int psize; | ||
66 | unsigned int pflags; | ||
67 | unsigned int pduration; | ||
68 | uint32_t serial; | ||
69 | uint64_t granule; | ||
70 | uint64_t start_granule; | ||
71 | int64_t lastpts; | ||
72 | int64_t lastdts; | ||
73 | int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet | ||
74 | int64_t page_pos; ///< file offset of the current page | ||
75 | int flags; | ||
76 | const struct ogg_codec *codec; | ||
77 | int header; | ||
78 | int nsegs, segp; | ||
79 | uint8_t segments[255]; | ||
80 | int incomplete; ///< whether we're expecting a continuation in the next page | ||
81 | int page_end; ///< current packet is the last one completed in the page | ||
82 | int keyframe_seek; | ||
83 | int got_start; | ||
84 | int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise | ||
85 | int nb_header; ///< set to the number of parsed headers | ||
86 | int start_trimming; ///< set the number of packets to drop from the start | ||
87 | int end_trimming; ///< set the number of packets to drop from the end | ||
88 | uint8_t *new_metadata; | ||
89 | size_t 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_dirac_codec; | ||
118 | extern const struct ogg_codec ff_flac_codec; | ||
119 | extern const struct ogg_codec ff_ogm_audio_codec; | ||
120 | extern const struct ogg_codec ff_ogm_old_codec; | ||
121 | extern const struct ogg_codec ff_ogm_text_codec; | ||
122 | extern const struct ogg_codec ff_ogm_video_codec; | ||
123 | extern const struct ogg_codec ff_old_dirac_codec; | ||
124 | extern const struct ogg_codec ff_old_flac_codec; | ||
125 | extern const struct ogg_codec ff_opus_codec; | ||
126 | extern const struct ogg_codec ff_skeleton_codec; | ||
127 | extern const struct ogg_codec ff_speex_codec; | ||
128 | extern const struct ogg_codec ff_theora_codec; | ||
129 | extern const struct ogg_codec ff_vorbis_codec; | ||
130 | extern const struct ogg_codec ff_vp8_codec; | ||
131 | |||
132 | /** | ||
133 | * Parse Vorbis comments | ||
134 | * | ||
135 | * @note The buffer will be temporarily modifed by this function, | ||
136 | * so it needs to be writable. Furthermore it must be padded | ||
137 | * by a single byte (not counted in size). | ||
138 | * All changes will have been reverted upon return. | ||
139 | */ | ||
140 | int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, | ||
141 | const uint8_t *buf, int size, int parse_picture); | ||
142 | |||
143 | /** | ||
144 | * Parse Vorbis comments and add metadata to an AVStream | ||
145 | * | ||
146 | * @note The buffer will be temporarily modifed by this function, | ||
147 | * so it needs to be writable. Furthermore it must be padded | ||
148 | * by a single byte (not counted in size). | ||
149 | * All changes will have been reverted upon return. | ||
150 | */ | ||
151 | int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, | ||
152 | const uint8_t *buf, int size); | ||
153 | |||
154 | static inline int | ||
155 | 1463 | ogg_find_stream (struct ogg * ogg, int serial) | |
156 | { | ||
157 | int i; | ||
158 | |||
159 |
2/2✓ Branch 0 taken 1437 times.
✓ Branch 1 taken 38 times.
|
1475 | for (i = 0; i < ogg->nstreams; i++) |
160 |
2/2✓ Branch 0 taken 1425 times.
✓ Branch 1 taken 12 times.
|
1437 | if (ogg->streams[i].serial == serial) |
161 | 1425 | return i; | |
162 | |||
163 | 38 | return -1; | |
164 | } | ||
165 | |||
166 | static inline uint64_t | ||
167 | 964 | ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) | |
168 | { | ||
169 | 964 | struct ogg *ogg = s->priv_data; | |
170 | 964 | struct ogg_stream *os = ogg->streams + i; | |
171 | 964 | uint64_t pts = AV_NOPTS_VALUE; | |
172 | |||
173 |
3/4✓ Branch 0 taken 964 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45 times.
✓ Branch 3 taken 919 times.
|
964 | if(os->codec && os->codec->gptopts){ |
174 | 45 | pts = os->codec->gptopts(s, i, gp, dts); | |
175 | } else { | ||
176 | 919 | pts = gp; | |
177 |
2/2✓ Branch 0 taken 545 times.
✓ Branch 1 taken 374 times.
|
919 | if (dts) |
178 | 545 | *dts = pts; | |
179 | } | ||
180 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 964 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
964 | if (pts > INT64_MAX && pts != AV_NOPTS_VALUE) { |
181 | // The return type is unsigned, we thus cannot return negative pts | ||
182 | ✗ | av_log(s, AV_LOG_ERROR, "invalid pts %"PRId64"\n", pts); | |
183 | ✗ | pts = AV_NOPTS_VALUE; | |
184 | } | ||
185 | |||
186 | 964 | return pts; | |
187 | } | ||
188 | |||
189 | #endif /* AVFORMAT_OGGDEC_H */ | ||
190 |