ogg: fix memory issue using shared pointers

This commit is contained in:
Frédéric Mangano
2016-03-01 16:24:47 +01:00
parent 0e3dfbe381
commit 53fbf533fb
4 changed files with 18 additions and 14 deletions

View File

@ -4,7 +4,7 @@ using namespace opustags;
void opustags::list_tags(ogg::Decoder &dec, ITagsHandler &handler)
{
ogg::Stream *s;
std::shared_ptr<ogg::Stream> s;
while (!handler.done()) {
s = dec.read_page();
if (s == nullptr)
@ -27,7 +27,7 @@ void opustags::list_tags(ogg::Decoder &dec, ITagsHandler &handler)
void opustags::edit_tags(
ogg::Decoder &in, ogg::Encoder &out, ITagsHandler &handler)
{
ogg::Stream *s;
std::shared_ptr<ogg::Stream> s;
while (true) {
s = in.read_page();
if (s == nullptr)

View File

@ -148,17 +148,18 @@ ogg::Decoder::~Decoder()
ogg_sync_clear(&sync);
}
ogg::Stream *ogg::Decoder::read_page()
std::shared_ptr<ogg::Stream> ogg::Decoder::read_page()
{
while (page_out()) {
int streamno = ogg_page_serialno(&current_page);
auto i = streams.find(streamno);
if (i == streams.end()) {
// we could check the page number to detect new streams (pageno = 0)
i = streams.emplace(streamno, Stream(streamno)).first;
auto s = std::make_shared<Stream>(streamno);
i = streams.emplace(streamno, s).first;
}
if (i->second.page_in(current_page))
return &(i->second);
if (i->second->page_in(current_page))
return i->second;
}
return nullptr; // end of stream
}
@ -207,9 +208,11 @@ ogg::Encoder::Encoder(std::ostream &out)
ogg::Stream& ogg::Encoder::get_stream(int streamno)
{
auto i = streams.find(streamno);
if (i == streams.end())
i = streams.emplace(streamno, Stream(streamno)).first;
return i->second;
if (i == streams.end()) {
auto s = std::make_shared<Stream>(streamno);
i = streams.emplace(streamno, s).first;
}
return *(i->second);
}
void ogg::Encoder::forward(ogg::Stream &in)
@ -261,7 +264,7 @@ void ogg::Encoder::write_tags(int streamno, const Tags &tags)
op.bytes = data.size();
op.packet = reinterpret_cast<unsigned char*>(const_cast<char*>(data.data()));
ogg::Stream *s = &streams.at(streamno); // assume it exists
std::shared_ptr<ogg::Stream> s = streams.at(streamno); // assume it exists
if (ogg_stream_packetin(&s->stream, &op) != 0)
throw std::runtime_error("ogg_stream_packetin failed");
flush_stream(*s);

View File

@ -4,6 +4,7 @@
#include <iostream>
#include <map>
#include <memory>
#include <ogg/ogg.h>
namespace opustags {
@ -79,13 +80,13 @@ namespace ogg
// The read page is given to Stream::page_in before this function
// returns.
// After the end of the file is reached, it returns NULL.
Stream *read_page();
std::shared_ptr<Stream> read_page();
std::istream &input;
ogg_sync_state sync;
ogg_page current_page;
std::map<int, Stream> streams;
std::map<int, std::shared_ptr<Stream>> streams;
private:
bool page_out();
@ -110,7 +111,7 @@ namespace ogg
// We're gonna need some ogg_stream_state for adjusting the page
// numbers and splitting large packets as it's gotta be done.
std::map<int, Stream> streams;
std::map<int, std::shared_ptr<Stream>> streams;
private:
Stream& get_stream(int streamno);

View File

@ -13,7 +13,7 @@ SCENARIO("decoding a single-stream file", "[ogg]")
ogg::Decoder dec(src);
WHEN("reading the first page") {
ogg::Stream *s = dec.read_page();
std::shared_ptr<ogg::Stream> s = dec.read_page();
THEN("the Opus header is ready") {
REQUIRE(s != nullptr);
REQUIRE(s->state == ogg::HEADER_READY);