reduce write_packet and flush_page into write_header_packet

This commit is contained in:
Frédéric Mangano-Tarumi 2018-12-05 17:37:59 -05:00
parent 1ff5284b60
commit 7e575ffbc3
3 changed files with 23 additions and 73 deletions

View File

@ -71,6 +71,9 @@ ot::status ot::ogg_reader::read_packet()
return {st::libogg_error, "ogg_stream_packetout failed"};
}
/**
* \todo Make sure the page doesn't begin new packets that are continued on the following page.
*/
ot::status ot::ogg_reader::read_header_packet(const std::function<status(ogg_packet&)>& f)
{
ot::status rc = read_packet();
@ -122,31 +125,23 @@ ot::status ot::ogg_writer::prepare_stream(long serialno)
return st::ok;
}
ot::status ot::ogg_writer::write_packet(const ogg_packet& packet)
{
if (ogg_stream_packetin(&stream, const_cast<ogg_packet*>(&packet)) != 0)
return {st::libogg_error, "ogg_stream_packetin failed"};
else
return st::ok;
}
ot::status ot::ogg_writer::write_header_packet(const ogg_packet& packet)
{
ot::status rc;
if ((rc = write_packet(packet)) != ot::st::ok)
return rc;
return flush_page();
}
/**
* \todo What if the packet is too big to fit a single page?
*/
ot::status ot::ogg_writer::flush_page()
ot::status ot::ogg_writer::write_header_packet(ogg_packet& packet)
{
if (ogg_stream_packetin(&stream, &packet) != 0)
return {ot::st::libogg_error, "ogg_stream_packetin failed"};
ogg_page page;
if (ogg_stream_flush(&stream, &page) != 0) {
ot::status rc = write_page(page);
if (rc != ot::st::ok)
return rc;
} else {
return {ot::st::libogg_error, "ogg_stream_flush failed"};
}
if (ogg_stream_flush(&stream, &page) != 0)
return write_page(page);
return {ot::st::error,
"Header packets spanning multiple pages are not yet supported. "
"Please file an issue to make your wish known."};
if (ogg_stream_check(&stream) != 0)
return {st::libogg_error, "ogg_stream_check failed"};
return st::ok; /* nothing was done */
return ot::st::ok;
}

View File

@ -247,13 +247,6 @@ private:
/**
* An Ogg writer lets you write ogg_page objets to an output file, and assemble packets into pages.
*
* It has two modes of operations :
* 1. call #write_page, or
* 2. call #prepare_stream, then #write_packet one or more times, followed by #flush_page.
*
* You can switch between the two modes, but must not start writing packets and then pages without
* flushing.
*/
class ogg_writer {
public:
@ -283,31 +276,11 @@ public:
* \todo Merge into #write_header_packet.
*/
status prepare_stream(long serialno);
/**
* Add a packet to the current page under assembly.
*
* If the packet is coming from a different page, make sure the serial number fits by
* calling #prepare_stream.
*
* When the page is complete, you should call #flush_page to finalize the page.
*
* You must not call #write_page after it, until you call #flush_page.
*
* \todo Merge into #write_header_packet.
*/
status write_packet(const ogg_packet& packet);
/**
* Write a header packet and flush the page. Header packets are always placed alone on their
* pages.
*/
status write_header_packet(const ogg_packet& packet);
/**
* Write the page under assembly. Future calls to #write_packet will be written in a new
* page.
*
* \todo Merge into #write_header_packet.
*/
status flush_page();
status write_header_packet(ogg_packet& packet);
private:
/**
* The stream state receives packets and generates pages.

View File

@ -63,9 +63,8 @@ static bool same_packet(const ogg_packet& lhs, const ogg_packet& rhs)
*/
static void check_memory_ogg()
{
const ogg_packet first_packet = make_packet("First");
const ogg_packet second_packet = make_packet("Second");
const ogg_packet third_packet = make_packet("Third");
ogg_packet first_packet = make_packet("First");
ogg_packet second_packet = make_packet("Second");
std::vector<unsigned char> my_ogg(128);
size_t my_ogg_size;
ot::status rc;
@ -78,26 +77,17 @@ static void check_memory_ogg()
rc = writer.prepare_stream(1234);
if (rc != ot::st::ok)
throw failure("could not prepare the stream for the first page");
writer.write_packet(first_packet);
writer.write_header_packet(first_packet);
if (rc != ot::st::ok)
throw failure("could not write the first packet");
writer.flush_page();
if (rc != ot::st::ok)
throw failure("could not flush the first page");
writer.prepare_stream(1234);
if (rc != ot::st::ok)
throw failure("could not prepare the stream for the second page");
writer.write_packet(second_packet);
writer.write_header_packet(second_packet);
if (rc != ot::st::ok)
throw failure("could not write the second packet");
writer.write_packet(third_packet);
if (rc != ot::st::ok)
throw failure("could not write the third packet");
writer.flush_page();
if (rc != ot::st::ok)
throw failure("could not flush the second page");
my_ogg_size = ftell(output.get());
if (my_ogg_size != 73)
if (my_ogg_size != 67)
throw failure("unexpected output size");
}
@ -125,14 +115,6 @@ static void check_memory_ogg()
throw failure("could not read the second packet");
if (!same_packet(reader.packet, second_packet))
throw failure("unexpected content in the second packet");
rc = reader.read_packet();
if (rc != ot::st::ok)
throw failure("could not read the third packet");
if (!same_packet(reader.packet, third_packet))
throw failure("unexpected content in the third packet");
rc = reader.read_packet();
if (rc != ot::st::end_of_page)
throw failure("unexpected third packet in the second page");
rc = reader.read_page();
if (rc != ot::st::end_of_stream)
throw failure("unexpected third page");