mirror of
https://github.com/fmang/opustags.git
synced 2024-11-10 07:27:22 +01:00
introduce ot::is_opus_stream
This commit is contained in:
parent
f080f9da70
commit
23049a7ff6
@ -14,6 +14,15 @@
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
bool ot::is_opus_stream(const ogg_page& identification_header)
|
||||
{
|
||||
if (ogg_page_bos(&identification_header) == 0)
|
||||
return false;
|
||||
if (identification_header.body_len < 8)
|
||||
return false;
|
||||
return (memcmp(identification_header.body, "OpusHead", 8) == 0);
|
||||
}
|
||||
|
||||
ot::status ot::ogg_reader::read_page()
|
||||
{
|
||||
while (ogg_sync_pageout(&sync, &page) != 1) {
|
||||
|
@ -146,6 +146,13 @@ struct ogg_logical_stream : ogg_stream_state {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Identify the codec of a logical stream based on the first bytes of the first packet of the first
|
||||
* page. For Opus, the first 8 bytes must be OpusHead. Any other signature is assumed to be another
|
||||
* codec.
|
||||
*/
|
||||
bool is_opus_stream(const ogg_page& identification_header);
|
||||
|
||||
/**
|
||||
* Ogg reader, combining a FILE input, an ogg_sync_state reading the pages.
|
||||
*
|
||||
|
38
t/ogg.cc
38
t/ogg.cc
@ -14,6 +14,8 @@ static void check_ref_ogg()
|
||||
ot::status rc = reader.read_page();
|
||||
if (rc != ot::st::ok)
|
||||
throw failure("could not read the first page");
|
||||
if (!ot::is_opus_stream(reader.page))
|
||||
throw failure("failed to identify the stream as opus");
|
||||
rc = reader.read_header_packet([](ogg_packet& p) {
|
||||
if (p.bytes != 19)
|
||||
throw failure("unexpected length for the first packet");
|
||||
@ -114,10 +116,44 @@ static void check_memory_ogg()
|
||||
}
|
||||
}
|
||||
|
||||
void check_identification()
|
||||
{
|
||||
auto good_header = (unsigned char*)
|
||||
"\x4f\x67\x67\x53\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x42\xf2"
|
||||
"\xe6\xc7\x00\x00\x00\x00\x7e\xc3\x57\x2b\x01\x13";
|
||||
auto good_body = (unsigned char*) "OpusHeadABCD";
|
||||
|
||||
ogg_page id;
|
||||
id.header = good_header;
|
||||
id.header_len = 28;
|
||||
id.body = good_body;
|
||||
id.body_len = 12;
|
||||
if (!ot::is_opus_stream(id))
|
||||
throw failure("could not identify opus header");
|
||||
|
||||
// Bad body
|
||||
id.body_len = 7;
|
||||
if (ot::is_opus_stream(id))
|
||||
throw failure("opus header was too short to be valid");
|
||||
id.body_len = 12;
|
||||
id.body = (unsigned char*) "Not_OpusHead";
|
||||
if (ot::is_opus_stream(id))
|
||||
throw failure("was not an opus header");
|
||||
id.body = good_body;
|
||||
|
||||
// Remove the BoS bit from the header.
|
||||
id.header = (unsigned char*)
|
||||
"\x4f\x67\x67\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x42\xf2"
|
||||
"\xe6\xc7\x00\x00\x00\x00\x7e\xc3\x57\x2b\x01\x13";
|
||||
if (ot::is_opus_stream(id))
|
||||
throw failure("was not the beginning of a stream");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::cout << "1..2\n";
|
||||
std::cout << "1..3\n";
|
||||
run(check_ref_ogg, "check a reference ogg stream");
|
||||
run(check_memory_ogg, "build and check a fresh stream");
|
||||
run(check_identification, "stream identification");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user