1 #ifndef _library__ogg__hpp__included__
2 #define _library__ogg__hpp__included__
12 * A packet in Ogg bitstream.
24 packet(uint64_t granule
, bool first
, bool last
, bool spans
, bool eos
, bool bos
,
25 const std::vector
<uint8_t>& d
);
27 * Is the packet first within its page?
29 bool get_first_page() const throw() { return first_page
; }
31 * Is the packet last within its page?
33 bool get_last_page() const throw() { return last_page
; }
35 * Is the packet spanning multiple pages?
37 bool get_spans_page() const throw() { return spans_page
; }
39 * Is atomic (first, last and on one page)?
41 bool get_atomic() const throw() { return first_page
&& last_page
&& !spans_page
; }
43 * Get the granule position within page the packet finished at.
45 uint64_t get_granulepos() const throw() { return granulepos
; }
47 * Does the page this ends on have EOS set?
49 bool get_on_eos_page() const throw() { return eos_page
; }
51 * Does the page this starts on have BOS set?
53 bool get_on_bos_page() const throw() { return bos_page
; }
55 * Get the packet data.
57 const std::vector
<uint8_t>& get_vector() const throw() { return data
; }
59 * Get length of packet data.
61 size_t get_length() const throw() { return data
.size(); }
65 const uint8_t* get_data() const throw() { return &data
[0]; }
73 std::vector
<uint8_t> data
;
77 * A page in Ogg bitstream.
83 * Create a new blank page.
87 * Create a page, reading a buffer.
89 * Parameter buffer: The buffer to read.
90 * Parameter advance: The number of bytes in packet is stored here.
91 * Throws std::runtime_error: Bad packet.
93 page(const char* buffer
, size_t& advance
);
95 * Scan a buffer for pages.
97 * Parameter buffer: The buffer to scan.
98 * Parameter bufferlen: The length of buffer. Should be at least 65307, unless there's not that much available.
99 * Parameter eof: If set, assume physical stream ends after this buffer.
100 * Parameter advance: Amount to advance the pointer is stored here.
101 * Returns: True if packet was found, false if not.
103 static bool scan(const char* buffer
, size_t bufferlen
, bool eof
, size_t& advance
) throw();
105 * Get the continue flag of packet.
107 bool get_continue() const throw() { return flag_continue
; }
109 * Set the continue flag of packet.
111 void set_continue(bool c
) throw() { flag_continue
= c
; }
113 * Get the BOS flag of packet.
115 bool get_bos() const throw() { return flag_bos
; }
117 * Set the BOS flag of packet.
119 void set_bos(bool b
) throw() { flag_bos
= b
; }
121 * Get the EOS flag of packet.
123 bool get_eos() const throw() { return flag_eos
; }
125 * Set the EOS flag of packet.
127 void set_eos(bool e
) throw() { flag_eos
= e
; }
129 * Get the granulepos of packet.
131 uint64_t get_granulepos() const throw() { return granulepos
; }
133 * Set the granulepos of packet.
135 void set_granulepos(uint64_t g
) throw() { granulepos
= g
; }
137 * Get stream identifier.
139 uint32_t get_stream() const throw() { return stream
; }
141 * Set stream identifier.
143 void set_stream(uint32_t s
) throw() { stream
= s
; }
145 * Get stream identifier.
147 uint32_t get_sequence() const throw() { return sequence
; }
149 * Set stream identifier.
151 void set_sequence(uint32_t s
) throw() { sequence
= s
; }
153 * Get number of packets.
155 uint8_t get_packet_count() const throw() { return packet_count
; }
159 std::pair
<const uint8_t*, size_t> get_packet(size_t packetno
) const throw()
161 if(packetno
>= packet_count
)
162 return std::make_pair(reinterpret_cast<const uint8_t*>(NULL
), 0);
164 return std::make_pair(data
+ packets
[packetno
], packets
[packetno
+ 1] - packets
[packetno
]);
167 * Get the last packet incomplete flag.
169 bool get_last_packet_incomplete() const throw() { return last_incomplete
; }
171 * Get amount of data that can be written as a complete packet.
173 size_t get_max_complete_packet() const throw();
175 * Append a complete packet to page.
177 * Parameter d: The data to append.
178 * Parameter dlen: The length of data to append.
179 * Returns: True on success, false on failure.
181 bool append_packet(const uint8_t* d
, size_t dlen
) throw();
183 * Append a possibly incomplete packet to page.
185 * Parameter d: The data to append. Adjusted.
186 * Parameter dlen: The length of data to append. Adjusted
187 * Returns: True if write was complete, false if incomplete.
189 bool append_packet_incomplete(const uint8_t*& d
, size_t& dlen
) throw();
191 * Get number of octets it takes to serialize this.
193 size_t serialize_size() const throw() { return 27 + segment_count
+ data_count
; }
195 * Serialize this packet.
197 * Parameter buffer: Buffer to serialize to (use serialize_size() to find the size).
199 void serialize(char* buffer
) const throw();
201 * Get debugging info for stream this page is from.
203 std::string
stream_debug_id() const;
205 * Get debugging info for this page.
207 std::string
page_debug_id() const;
209 * The special granule pos for nothing.
211 const static uint64_t granulepos_none
;
217 bool last_incomplete
;
221 uint8_t segment_count
;
222 uint8_t packet_count
;
225 uint8_t segments
[255];
226 uint16_t packets
[256];
236 * Create a new demuxer.
238 demuxer(std::ostream
& _errors_to
);
240 * Demuxer wants a page in?
242 bool wants_page_in() const throw() { return (dpacket
== packets
&& !ended
); }
244 * Demuxer wants a packet out?
246 bool wants_packet_out() const throw() { return (dpacket
< packets
); }
250 bool page_in(const page
& p
);
254 void packet_out(packet
& pkt
);
258 void discard_packet();
260 uint32_t inc1(uint32_t x
) { return x
+ 1; }
261 uint64_t page_fullseq(uint32_t seq
);
262 void update_pageseq(uint32_t new_seq
);
263 bool complain_lost_page(uint32_t new_seq
, uint32_t stream
);
264 void complain_continue_errors(unsigned flags
, uint32_t seqno
, uint32_t stream
, uint32_t pkts
,
266 std::ostream
& errors_to
;
267 std::vector
<uint8_t> partial
;
271 uint32_t imprint_stream
;
277 uint64_t last_granulepos
;
290 muxer(uint32_t streamid
, uint64_t _seq
= 0);
294 bool wants_packet_in() const throw();
296 * Packet of this size fits on current page?
298 bool packet_fits(size_t pktsize
) const throw();
300 * Has a page to output?
302 bool has_page_out() const throw();
306 void packet_in(const std::vector
<uint8_t>& data
, uint64_t granule
);
308 * Signal end of stream.
314 void page_out(page
& p
);
318 std::vector
<uint8_t> buffered
;
334 stream_reader() throw();
338 virtual ~stream_reader() throw();
342 * Parameter buffer: The buffer to store the data to.
343 * Parameter size: The maximum size to read.
344 * Returns: The number of bytes actually read.
346 virtual size_t read(char* buffer
, size_t size
) = 0;
348 * Read a page from stream.
350 * Parameter page: The page is assigned here if successful.
351 * Returns: True if page was obtained, false if not.
353 bool get_page(page
& page
);
355 * Set stream to report errors to.
357 * Parameter strm: The stream.
359 void set_errors_to(std::ostream
& os
);
361 * Starting offset of last packet returned.
363 uint64_t get_last_offset() { return last_offset
; }
365 stream_reader(const stream_reader
&);
366 stream_reader
& operator=(const stream_reader
&);
368 void discard_buffer(size_t amount
);
372 uint64_t last_offset
;
373 uint64_t start_offset
;
374 std::ostream
* errors_to
;
378 * Ogg stream reader based on std::istream.
380 class stream_reader_iostreams
: public stream_reader
386 * Parameter stream: The stream to read the data from.
388 stream_reader_iostreams(std::istream
& stream
);
392 ~stream_reader_iostreams() throw();
394 size_t read(char* buffer
, size_t size
);
408 stream_writer() throw();
412 virtual ~stream_writer() throw();
416 * Parameter data: The data to write.
417 * Parameter size: The size to write.
419 virtual void write(const char* buffer
, size_t size
) = 0;
421 * Write a page to stream.
423 * Parameter page: The page to write.
425 void put_page(const page
& page
);
427 stream_writer(const stream_writer
&);
428 stream_writer
& operator=(const stream_writer
&);
432 * Ogg stream writer based on std::istream.
434 class stream_writer_iostreams
: public stream_writer
440 * Parameter stream: The stream to read the data from.
442 stream_writer_iostreams(std::ostream
& stream
);
446 ~stream_writer_iostreams() throw();
448 void write(const char* buffer
, size_t size
);