partial implementation of ogg::Stream

This commit is contained in:
Frédéric Mangano
2016-02-23 11:21:00 +01:00
parent c2d6763e2b
commit ff17d35531
3 changed files with 88 additions and 6 deletions

View File

@ -16,6 +16,7 @@ void opustags::list_tags(ogg::Decoder &dec, TagsHandler &handler)
break;
case ogg::TAGS_READY:
handler.list(s->stream.serialno, s->tags);
s->downgrade(); // no more use for it
break;
default:
;

76
src/ogg.cc Normal file
View File

@ -0,0 +1,76 @@
#include "ogg.h"
#include <stdexcept>
using namespace opustags;
ogg::Stream::Stream(int streamno)
{
state = ogg::BEGIN_OF_STREAM;
type = ogg::UNKNOWN_STREAM;
if (ogg_stream_init(&stream, streamno) != 0)
throw std::runtime_error("ogg_stream_init failed");
}
ogg::Stream::~Stream()
{
ogg_stream_clear(&stream);
}
bool ogg::Stream::page_in(ogg_page &og)
{
if (state == ogg::RAW_READY)
return true;
if (ogg_stream_pagein(&stream, &og) != 0)
throw std::runtime_error("ogg_stream_pagein failed");
if (state == ogg::BEGIN_OF_STREAM || state == ogg::HEADER_READY) {
// We're expecting a header, so we parse it.
return handle_page();
} else {
// We're past the first two headers.
state = ogg::DATA_READY;
return true;
}
}
// Read the first packet of the page and parses it.
bool ogg::Stream::handle_page()
{
ogg_packet op;
int rc = ogg_stream_packetout(&stream, &op);
if (rc < 0)
throw std::runtime_error("ogg_stream_packetout failed");
else if (rc == 0) // insufficient data
return false; // asking for a new page
// We've read the first packet successfully.
// The headers are supposed to contain only one packet, so this is enough
// for us. Still, we could ensure there are no other packets.
handle_packet(op);
return true;
}
void ogg::Stream::handle_packet(const ogg_packet &op)
{
if (state == ogg::BEGIN_OF_STREAM)
parse_header(op);
else if (state == ogg::HEADER_READY)
parse_tags(op);
// else shrug
}
void ogg::Stream::parse_header(const ogg_packet &op)
{
// TODO
}
void ogg::Stream::parse_tags(const ogg_packet &op)
{
// TODO
}
void ogg::Stream::downgrade()
{
type = ogg::UNKNOWN_STREAM;
if (state != ogg::BEGIN_OF_STREAM && state != ogg::END_OF_STREAM)
state = RAW_READY;
}

View File

@ -1,12 +1,11 @@
#pragma once
#include <stdexcept>
#include "tags.h"
#include <iostream>
#include <map>
#include <ogg/ogg.h>
#include "tags.h"
namespace opustags {
namespace ogg
{
@ -30,13 +29,13 @@ namespace ogg
// not.
struct Stream
{
Stream(int serialno);
Stream(int streamno);
~Stream();
// Called by Decoder once a page was read.
// Returns true if it's ready, false if it expects more data.
// In the latter case, Decoder::read_page will keep reading.
bool page_in(const ogg_page&);
bool page_in(ogg_page&);
// Make the stream behave as if it were unknown.
// As a consequence, no more effort would be made in extracting data.
@ -61,6 +60,12 @@ namespace ogg
// need a new sequence number.
ogg_stream_state stream;
private:
bool handle_page();
void handle_packet(const ogg_packet&);
void parse_header(const ogg_packet&);
void parse_tags(const ogg_packet&);
};
struct Decoder
@ -93,7 +98,7 @@ namespace ogg
// needed for write_page.
void write_raw_page(const ogg_page&);
void write_tags(int serialno, const Tags&);
void write_tags(int streamno, const Tags&);
std::ostream output;