yading@11: /** yading@11: Copyright (C) 2005 Michael Ahlberg, Måns Rullgård yading@11: yading@11: Permission is hereby granted, free of charge, to any person yading@11: obtaining a copy of this software and associated documentation yading@11: files (the "Software"), to deal in the Software without yading@11: restriction, including without limitation the rights to use, copy, yading@11: modify, merge, publish, distribute, sublicense, and/or sell copies yading@11: of the Software, and to permit persons to whom the Software is yading@11: furnished to do so, subject to the following conditions: yading@11: yading@11: The above copyright notice and this permission notice shall be yading@11: included in all copies or substantial portions of the Software. yading@11: yading@11: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, yading@11: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF yading@11: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND yading@11: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT yading@11: HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, yading@11: WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, yading@11: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER yading@11: DEALINGS IN THE SOFTWARE. yading@11: **/ yading@11: yading@11: #ifndef AVFORMAT_OGGDEC_H yading@11: #define AVFORMAT_OGGDEC_H yading@11: yading@11: #include "avformat.h" yading@11: #include "metadata.h" yading@11: yading@11: struct ogg_codec { yading@11: const int8_t *magic; yading@11: uint8_t magicsize; yading@11: const int8_t *name; yading@11: /** yading@11: * Attempt to process a packet as a header yading@11: * @return 1 if the packet was a valid header, yading@11: * 0 if the packet was not a header (was a data packet) yading@11: * -1 if an error occurred or for unsupported stream yading@11: */ yading@11: int (*header)(AVFormatContext *, int); yading@11: int (*packet)(AVFormatContext *, int); yading@11: /** yading@11: * Translate a granule into a timestamp. yading@11: * Will set dts if non-null and known. yading@11: * @return pts yading@11: */ yading@11: uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); yading@11: /** yading@11: * 1 if granule is the start time of the associated packet. yading@11: * 0 if granule is the end time of the associated packet. yading@11: */ yading@11: int granule_is_start; yading@11: /** yading@11: * Number of expected headers yading@11: */ yading@11: int nb_header; yading@11: void (*cleanup)(AVFormatContext *s, int idx); yading@11: }; yading@11: yading@11: struct ogg_stream { yading@11: uint8_t *buf; yading@11: unsigned int bufsize; yading@11: unsigned int bufpos; yading@11: unsigned int pstart; yading@11: unsigned int psize; yading@11: unsigned int pflags; yading@11: unsigned int pduration; yading@11: uint32_t serial; yading@11: uint64_t granule; yading@11: uint64_t start_granule; yading@11: int64_t lastpts; yading@11: int64_t lastdts; yading@11: int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet yading@11: int64_t page_pos; ///< file offset of the current page yading@11: int flags; yading@11: const struct ogg_codec *codec; yading@11: int header; yading@11: int nsegs, segp; yading@11: uint8_t segments[255]; yading@11: int incomplete; ///< whether we're expecting a continuation in the next page yading@11: int page_end; ///< current packet is the last one completed in the page yading@11: int keyframe_seek; yading@11: int got_start; yading@11: int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise yading@11: int nb_header; ///< set to the number of parsed headers yading@11: void *private; yading@11: }; yading@11: yading@11: struct ogg_state { yading@11: uint64_t pos; yading@11: int curidx; yading@11: struct ogg_state *next; yading@11: int nstreams; yading@11: struct ogg_stream streams[1]; yading@11: }; yading@11: yading@11: struct ogg { yading@11: struct ogg_stream *streams; yading@11: int nstreams; yading@11: int headers; yading@11: int curidx; yading@11: int64_t page_pos; ///< file offset of the current page yading@11: struct ogg_state *state; yading@11: }; yading@11: yading@11: #define OGG_FLAG_CONT 1 yading@11: #define OGG_FLAG_BOS 2 yading@11: #define OGG_FLAG_EOS 4 yading@11: yading@11: #define OGG_NOGRANULE_VALUE (-1ull) yading@11: yading@11: extern const struct ogg_codec ff_celt_codec; yading@11: extern const struct ogg_codec ff_dirac_codec; yading@11: extern const struct ogg_codec ff_flac_codec; yading@11: extern const struct ogg_codec ff_ogm_audio_codec; yading@11: extern const struct ogg_codec ff_ogm_old_codec; yading@11: extern const struct ogg_codec ff_ogm_text_codec; yading@11: extern const struct ogg_codec ff_ogm_video_codec; yading@11: extern const struct ogg_codec ff_old_dirac_codec; yading@11: extern const struct ogg_codec ff_old_flac_codec; yading@11: extern const struct ogg_codec ff_opus_codec; yading@11: extern const struct ogg_codec ff_skeleton_codec; yading@11: extern const struct ogg_codec ff_speex_codec; yading@11: extern const struct ogg_codec ff_theora_codec; yading@11: extern const struct ogg_codec ff_vorbis_codec; yading@11: yading@11: int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size); yading@11: yading@11: static inline int yading@11: ogg_find_stream (struct ogg * ogg, int serial) yading@11: { yading@11: int i; yading@11: yading@11: for (i = 0; i < ogg->nstreams; i++) yading@11: if (ogg->streams[i].serial == serial) yading@11: return i; yading@11: yading@11: return -1; yading@11: } yading@11: yading@11: static inline uint64_t yading@11: ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) yading@11: { yading@11: struct ogg *ogg = s->priv_data; yading@11: struct ogg_stream *os = ogg->streams + i; yading@11: uint64_t pts = AV_NOPTS_VALUE; yading@11: yading@11: if(os->codec && os->codec->gptopts){ yading@11: pts = os->codec->gptopts(s, i, gp, dts); yading@11: } else { yading@11: pts = gp; yading@11: if (dts) yading@11: *dts = pts; yading@11: } yading@11: yading@11: return pts; yading@11: } yading@11: yading@11: #endif /* AVFORMAT_OGGDEC_H */