hide the reader's stream in the ogg module

This commit is contained in:
Frédéric Mangano-Tarumi 2018-11-16 19:10:14 -05:00
parent 121220ea05
commit e22a1d381a
4 changed files with 54 additions and 20 deletions

View File

@ -267,10 +267,6 @@ ot::status ot::process(ogg_reader& reader, ogg_writer& writer, const ot::options
}
// Initialize the streams from the first page.
if (packet_count == -1) {
if (ogg_stream_init(&reader.stream, ogg_page_serialno(&reader.page)) == -1) {
error = "ogg_stream_init: couldn't create a decoder";
break;
}
if (writer.file) {
if (ogg_stream_init(&writer.stream, ogg_page_serialno(&reader.page)) == -1) {
error = "ogg_stream_init: couldn't create an encoder";
@ -279,12 +275,8 @@ ot::status ot::process(ogg_reader& reader, ogg_writer& writer, const ot::options
}
packet_count = 0;
}
if (ogg_stream_pagein(&reader.stream, &reader.page) == -1) {
error = "ogg_stream_pagein: invalid page";
break;
}
// Read all the packets.
while (ogg_stream_packetout(&reader.stream, &reader.packet) == 1) {
while ((rc = reader.read_packet()) == ot::status::ok) {
packet_count++;
if (packet_count == 1) { // Identification header
rc = ot::validate_identification_header(reader.packet);
@ -310,8 +302,8 @@ ot::status ot::process(ogg_reader& reader, ogg_writer& writer, const ot::options
}
}
}
if (ogg_stream_check(&reader.stream) != 0) {
error = "ogg_stream_check: internal error (decoder)";
if (rc != ot::status::ok && rc != ot::status::end_of_page) {
error = "error reading the ogg packets";
break;
}
// Write the page.

View File

@ -8,6 +8,8 @@ static const char* messages[] = {
"Integer overflow",
nullptr, /* standard error: call stderror */
"End of file",
"End of page",
"Stream is not ready",
"libogg error",
"Invalid identification header, not an Opus stream",
"Invalid comment header",

View File

@ -6,13 +6,13 @@ ot::ogg_reader::ogg_reader(FILE* input)
: file(input)
{
ogg_sync_init(&sync);
memset(&stream, 0, sizeof(stream));
}
ot::ogg_reader::~ogg_reader()
{
if (stream_ready)
ogg_stream_clear(&stream);
ogg_sync_clear(&sync);
ogg_stream_clear(&stream);
}
ot::status ot::ogg_reader::read_page()
@ -31,9 +31,31 @@ ot::status ot::ogg_reader::read_page()
if (ogg_sync_check(&sync) != 0)
return status::libogg_error;
}
if (!stream_ready) {
if (ogg_stream_init(&stream, ogg_page_serialno(&page)) == -1)
return status::libogg_error;
stream_ready = true;
}
stream_in_sync = false;
return status::ok;
}
ot::status ot::ogg_reader::read_packet()
{
if (!stream_ready)
return status::stream_not_ready;
/* If the stream is on a different page, feed the current page. */
if (!stream_in_sync) {
if (ogg_stream_pagein(&stream, &page) == -1)
return status::libogg_error;
stream_in_sync = true;
}
int rc = ogg_stream_packetout(&stream, &packet);
return rc == 0 ? status::end_of_page :
rc == 1 ? status::ok :
status::libogg_error;
}
ot::ogg_writer::ogg_writer(FILE* output)
: file(output)
{

View File

@ -35,6 +35,8 @@ enum class status {
/** On standard error, errno will give more details. */
standard_error,
end_of_file,
end_of_page,
stream_not_ready,
libogg_error,
bad_identification_header,
bad_comment_header,
@ -92,6 +94,13 @@ struct ogg_reader {
* call to #read_page. Make sure you also check #status::end_of_file.
*/
status read_page();
/**
* Read the next available packet from the current #page. The packet is available in the
* #packet field.
*
* If the end of page was reached, return #status::end_of_page.
*/
status read_packet();
/**
* The file is our source of binary data. It is not integrated to libogg, so we need to
* handle it ourselves.
@ -114,6 +123,22 @@ struct ogg_reader {
* to ogg_sync_pageout.
*/
ogg_page page;
/**
* Current packet from the stream state.
*
* Its memory is managed by libogg, inside the stream state, and is valid until the next
* call to ogg_stream_packetout.
*/
ogg_packet packet;
private:
/**
* Indicates whether the stream has been initialized or not.
*/
bool stream_ready = false;
/**
* Indicates if the stream's last fed page is the current one.
*/
bool stream_in_sync;
/**
* The stream layer receives pages and yields a sequence of packets.
*
@ -124,13 +149,6 @@ struct ogg_reader {
* After we've read OpusHead and OpusTags, we don't need the stream layer anymore.
*/
ogg_stream_state stream;
/**
* Current packet from the stream state.
*
* Its memory is managed by libogg, inside the stream state, and is valid until the next
* call to ogg_stream_packetout.
*/
ogg_packet packet;
};
struct ogg_writer {