mirror of
https://github.com/fmang/opustags.git
synced 2025-07-08 02:24:30 +02:00
partial implementation of ogg::Stream
This commit is contained in:
@ -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
76
src/ogg.cc
Normal 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;
|
||||
}
|
17
src/ogg.h
17
src/ogg.h
@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user