ogg: emit HEADER_READY on unknown streams too

This commit is contained in:
Frédéric Mangano 2016-03-30 14:01:11 +02:00
parent 5ae31c9bc9
commit a21331057b
4 changed files with 24 additions and 11 deletions

View File

@ -13,7 +13,9 @@ void opustags::list_tags(ogg::Decoder &dec, ITagsHandler &handler)
}
switch (s->state) {
case ogg::HEADER_READY:
if (!handler.relevant(s->stream.serialno))
if (s->type == ogg::UNKNOWN_STREAM)
; // ignore
else if (!handler.relevant(s->stream.serialno))
s->downgrade();
break;
case ogg::TAGS_READY:
@ -37,7 +39,9 @@ void opustags::edit_tags(
switch (s->state) {
case ogg::HEADER_READY:
if (!handler.relevant(s->stream.serialno)) {
if (s->type == ogg::UNKNOWN_STREAM) {
out.write_raw_page(in.current_page);
} else if (!handler.relevant(s->stream.serialno)) {
s->downgrade();
out.write_raw_page(in.current_page);
} else {

View File

@ -32,8 +32,10 @@ void ogg::Stream::flush_packets()
bool ogg::Stream::page_in(ogg_page &og)
{
if (state == ogg::RAW_READY)
if (state != ogg::BEGIN_OF_STREAM && type == ogg::UNKNOWN_STREAM) {
state = ogg::RAW_READY;
return true;
}
flush_packets(); // otherwise packet_out keeps returning the same packet
if (ogg_stream_pagein(&stream, &og) != 0)
throw std::runtime_error("ogg_stream_pagein failed");
@ -75,13 +77,11 @@ void ogg::Stream::handle_packet(const ogg_packet &op)
void ogg::Stream::parse_header(const ogg_packet &op)
{
if (op.bytes >= 8 && memcmp(op.packet, "OpusHead", 8) == 0) {
if (op.bytes >= 8 && memcmp(op.packet, "OpusHead", 8) == 0)
type = OPUS_STREAM;
state = HEADER_READY;
} else {
else
type = UNKNOWN_STREAM;
state = RAW_READY;
}
state = HEADER_READY;
}
// For reference:

View File

@ -49,7 +49,7 @@ namespace ogg
// Here are the meanings of the state variable:
// BEGIN_OF_STREAM: the stream was just initialized,
// HEADER_READY: the header is parsed and we know the type,
// HEADER_READY: the header (first packet) was found,
// TAGS_READY: the tags are parsed and complete,
// DATA_READY: we've read a data page whose meaning is no concern to us,
// RAW_READY: we don't even know what kind of stream that is, so don't alter it,
@ -61,6 +61,11 @@ namespace ogg
// tags grow and span over two pages, all the following pages are gonna
// need a new sequence number.
// For an Opus stream, the sequence will be:
// BEGIN_OF_STREAM → HEADER_READY → TAGS_READY → DATA_READY* → END_OF_STREAM
// For an unknown stream:
// BEGIN_OF_STREAM → HEADER_READY → RAW_READY* → END_OF_STREAM
ogg_stream_state stream;
private:

View File

@ -36,8 +36,12 @@ TEST_CASE("decoding an Ogg Vorbis file", "[ogg]")
std::shared_ptr<ogg::Stream> s = dec.read_page();
REQUIRE(s != nullptr);
REQUIRE(s->state == ogg::RAW_READY);
REQUIRE(s->state == ogg::HEADER_READY);
REQUIRE(s->type == ogg::UNKNOWN_STREAM);
s = dec.read_page();
REQUIRE(s != nullptr);
REQUIRE(s->state == ogg::RAW_READY);
}
TEST_CASE("decoding a multi-stream file", "[ogg]")
@ -56,7 +60,7 @@ TEST_CASE("decoding a multi-stream file", "[ogg]")
second = s;
REQUIRE(s != nullptr);
REQUIRE(s != first);
REQUIRE(s->state == ogg::RAW_READY);
REQUIRE(s->state == ogg::HEADER_READY);
REQUIRE(s->type == ogg::UNKNOWN_STREAM);
s = dec.read_page();