1 #ifndef _library__ogg__hpp__included__
2 #define _library__ogg__hpp__included__
10 * A packet in Ogg bitstream.
22 ogg_packet(uint64_t granule
, bool first
, bool last
, bool spans
, bool eos
, bool bos
,
23 const std::vector
<uint8_t>& d
);
25 * Is the packet first within its page?
27 bool get_first_page() const throw() { return first_page
; }
29 * Is the packet last within its page?
31 bool get_last_page() const throw() { return last_page
; }
33 * Is the packet spanning multiple pages?
35 bool get_spans_page() const throw() { return spans_page
; }
37 * Is atomic (first, last and on one page)?
39 bool get_atomic() const throw() { return first_page
&& last_page
&& !spans_page
; }
41 * Get the granule position within page the packet finished at.
43 uint64_t get_granulepos() const throw() { return granulepos
; }
45 * Does the page this ends on have EOS set?
47 bool get_on_eos_page() const throw() { return eos_page
; }
49 * Does the page this starts on have BOS set?
51 bool get_on_bos_page() const throw() { return bos_page
; }
53 * Get the packet data.
55 const std::vector
<uint8_t>& get_vector() const throw() { return data
; }
57 * Get length of packet data.
59 size_t get_length() const throw() { return data
.size(); }
63 const uint8_t* get_data() const throw() { return &data
[0]; }
71 std::vector
<uint8_t> data
;
75 * A page in Ogg bitstream.
81 * Create a new blank page.
85 * Create a page, reading a buffer.
87 * Parameter buffer: The buffer to read.
88 * Parameter advance: The number of bytes in packet is stored here.
89 * Throws std::runtime_error: Bad packet.
91 ogg_page(const char* buffer
, size_t& advance
) throw(std::runtime_error
);
93 * Scan a buffer for pages.
95 * Parameter buffer: The buffer to scan.
96 * Parameter bufferlen: The length of buffer. Should be at least 65307, unless there's not that much available.
97 * Parameter eof: If set, assume physical stream ends after this buffer.
98 * Parameter advance: Amount to advance the pointer is stored here.
99 * Returns: True if packet was found, false if not.
101 static bool scan(const char* buffer
, size_t bufferlen
, bool eof
, size_t& advance
) throw();
103 * Get the continue flag of packet.
105 bool get_continue() const throw() { return flag_continue
; }
107 * Set the continue flag of packet.
109 void set_continue(bool c
) throw() { flag_continue
= c
; }
111 * Get the BOS flag of packet.
113 bool get_bos() const throw() { return flag_bos
; }
115 * Set the BOS flag of packet.
117 void set_bos(bool b
) throw() { flag_bos
= b
; }
119 * Get the EOS flag of packet.
121 bool get_eos() const throw() { return flag_eos
; }
123 * Set the EOS flag of packet.
125 void set_eos(bool e
) throw() { flag_eos
= e
; }
127 * Get the granulepos of packet.
129 uint64_t get_granulepos() const throw() { return granulepos
; }
131 * Set the granulepos of packet.
133 void set_granulepos(uint64_t g
) throw() { granulepos
= g
; }
135 * Get stream identifier.
137 uint32_t get_stream() const throw() { return stream
; }
139 * Set stream identifier.
141 void set_stream(uint32_t s
) throw() { stream
= s
; }
143 * Get stream identifier.
145 uint32_t get_sequence() const throw() { return sequence
; }
147 * Set stream identifier.
149 void set_sequence(uint32_t s
) throw() { sequence
= s
; }
151 * Get number of packets.
153 uint8_t get_packet_count() const throw() { return packet_count
; }
157 std::pair
<const uint8_t*, size_t> get_packet(size_t packetno
) const throw()
159 if(packetno
>= packet_count
)
160 return std::make_pair(reinterpret_cast<const uint8_t*>(NULL
), 0);
162 return std::make_pair(data
+ packets
[packetno
], packets
[packetno
+ 1] - packets
[packetno
]);
165 * Get the last packet incomplete flag.
167 bool get_last_packet_incomplete() const throw() { return last_incomplete
; }
169 * Get amount of data that can be written as a complete packet.
171 size_t get_max_complete_packet() const throw();
173 * Append a complete packet to page.
175 * Parameter d: The data to append.
176 * Parameter dlen: The length of data to append.
177 * Returns: True on success, false on failure.
179 bool append_packet(const uint8_t* d
, size_t dlen
) throw();
181 * Append a possibly incomplete packet to page.
183 * Parameter d: The data to append. Adjusted.
184 * Parameter dlen: The length of data to append. Adjusted
185 * Returns: True if write was complete, false if incomplete.
187 bool append_packet_incomplete(const uint8_t*& d
, size_t& dlen
) throw();
189 * Get number of octets it takes to serialize this.
191 size_t serialize_size() const throw() { return 27 + segment_count
+ data_count
; }
193 * Serialize this packet.
195 * Parameter buffer: Buffer to serialize to (use serialize_size() to find the size).
197 void serialize(char* buffer
) const throw();
199 * Get debugging info for stream this page is from.
201 std::string
stream_debug_id() const throw(std::bad_alloc
);
203 * Get debugging info for this page.
205 std::string
page_debug_id() const throw(std::bad_alloc
);
207 * The special granule pos for nothing.
209 const static uint64_t granulepos_none
;
215 bool last_incomplete
;
219 uint8_t segment_count
;
220 uint8_t packet_count
;
223 uint8_t segments
[255];
224 uint16_t packets
[256];
234 * Create a new demuxer.
236 ogg_demuxer(std::ostream
& _errors_to
);
238 * Demuxer wants a page in?
240 bool wants_page_in() const throw() { return (packet
== packets
&& !ended
); }
242 * Demuxer wants a packet out?
244 bool wants_packet_out() const throw() { return (packet
< packets
); }
248 bool page_in(const ogg_page
& p
);
252 void packet_out(ogg_packet
& pkt
);
256 void discard_packet();
258 uint32_t inc1(uint32_t x
) { return x
+ 1; }
259 uint64_t page_fullseq(uint32_t seq
);
260 void update_pageseq(uint32_t new_seq
);
261 bool complain_lost_page(uint32_t new_seq
, uint32_t stream
);
262 void complain_continue_errors(unsigned flags
, uint32_t seqno
, uint32_t stream
, uint32_t pkts
,
264 std::ostream
& errors_to
;
265 std::vector
<uint8_t> partial
;
269 uint32_t imprint_stream
;
275 uint64_t last_granulepos
;
288 ogg_muxer(uint32_t streamid
, uint64_t _seq
= 0);
292 bool wants_packet_in() const throw();
294 * Packet of this size fits on current page?
296 bool packet_fits(size_t pktsize
) const throw();
298 * Has a page to output?
300 bool has_page_out() const throw();
304 void packet_in(const std::vector
<uint8_t>& data
, uint64_t granule
);
306 * Signal end of stream.
312 void page_out(ogg_page
& p
);
316 std::vector
<uint8_t> buffered
;
326 class ogg_stream_reader
332 ogg_stream_reader() throw();
336 virtual ~ogg_stream_reader() throw();
340 * Parameter buffer: The buffer to store the data to.
341 * Parameter size: The maximum size to read.
342 * Returns: The number of bytes actually read.
344 virtual size_t read(char* buffer
, size_t size
) throw(std::exception
) = 0;
346 * Read a page from stream.
348 * Parameter page: The page is assigned here if successful.
349 * Returns: True if page was obtained, false if not.
351 bool get_page(ogg_page
& page
) throw(std::exception
);
353 * Set stream to report errors to.
355 * Parameter strm: The stream.
357 void set_errors_to(std::ostream
& os
);
359 * Starting offset of last packet returned.
361 uint64_t get_last_offset() { return last_offset
; }
363 ogg_stream_reader(const ogg_stream_reader
&);
364 ogg_stream_reader
& operator=(const ogg_stream_reader
&);
366 void discard_buffer(size_t amount
);
370 uint64_t last_offset
;
371 uint64_t start_offset
;
372 std::ostream
* errors_to
;
376 * Ogg stream reader based on std::istream.
378 class ogg_stream_reader_iostreams
: public ogg_stream_reader
384 * Parameter stream: The stream to read the data from.
386 ogg_stream_reader_iostreams(std::istream
& stream
);
390 ~ogg_stream_reader_iostreams() throw();
392 size_t read(char* buffer
, size_t size
) throw(std::exception
);
400 class ogg_stream_writer
406 ogg_stream_writer() throw();
410 virtual ~ogg_stream_writer() throw();
414 * Parameter data: The data to write.
415 * Parameter size: The size to write.
417 virtual void write(const char* buffer
, size_t size
) throw(std::exception
) = 0;
419 * Write a page to stream.
421 * Parameter page: The page to write.
423 void put_page(const ogg_page
& page
) throw(std::exception
);
425 ogg_stream_writer(const ogg_stream_writer
&);
426 ogg_stream_writer
& operator=(const ogg_stream_writer
&);
430 * Ogg stream writer based on std::istream.
432 class ogg_stream_writer_iostreams
: public ogg_stream_writer
438 * Parameter stream: The stream to read the data from.
440 ogg_stream_writer_iostreams(std::ostream
& stream
);
444 ~ogg_stream_writer_iostreams() throw();
446 void write(const char* buffer
, size_t size
) throw(std::exception
);