decoder/opus: use class OggStreamState in _stream_decode()
This commit is contained in:
@@ -74,7 +74,7 @@ class MPDOpusDecoder {
|
|||||||
Decoder &decoder;
|
Decoder &decoder;
|
||||||
InputStream &input_stream;
|
InputStream &input_stream;
|
||||||
|
|
||||||
ogg_stream_state os;
|
OggStreamState os;
|
||||||
|
|
||||||
OpusDecoder *opus_decoder = nullptr;
|
OpusDecoder *opus_decoder = nullptr;
|
||||||
opus_int16 *output_buffer = nullptr;
|
opus_int16 *output_buffer = nullptr;
|
||||||
@@ -87,8 +87,6 @@ class MPDOpusDecoder {
|
|||||||
*/
|
*/
|
||||||
unsigned previous_channels = 0;
|
unsigned previous_channels = 0;
|
||||||
|
|
||||||
bool os_initialized = false;
|
|
||||||
|
|
||||||
int opus_serialno;
|
int opus_serialno;
|
||||||
|
|
||||||
ogg_int64_t eos_granulepos;
|
ogg_int64_t eos_granulepos;
|
||||||
@@ -97,11 +95,13 @@ class MPDOpusDecoder {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
MPDOpusDecoder(Decoder &_decoder,
|
MPDOpusDecoder(Decoder &_decoder,
|
||||||
InputStream &_input_stream)
|
InputStream &_input_stream,
|
||||||
:decoder(_decoder), input_stream(_input_stream) {}
|
ogg_page &first_page)
|
||||||
|
:decoder(_decoder), input_stream(_input_stream),
|
||||||
|
os(first_page) {}
|
||||||
|
|
||||||
~MPDOpusDecoder();
|
~MPDOpusDecoder();
|
||||||
|
|
||||||
bool ReadFirstPage(OggSyncState &oy);
|
|
||||||
bool ReadNextPage(OggSyncState &oy);
|
bool ReadNextPage(OggSyncState &oy);
|
||||||
|
|
||||||
DecoderCommand HandlePackets();
|
DecoderCommand HandlePackets();
|
||||||
@@ -120,37 +120,20 @@ MPDOpusDecoder::~MPDOpusDecoder()
|
|||||||
|
|
||||||
if (opus_decoder != nullptr)
|
if (opus_decoder != nullptr)
|
||||||
opus_decoder_destroy(opus_decoder);
|
opus_decoder_destroy(opus_decoder);
|
||||||
|
|
||||||
if (os_initialized)
|
|
||||||
ogg_stream_clear(&os);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
MPDOpusDecoder::ReadFirstPage(OggSyncState &oy)
|
|
||||||
{
|
|
||||||
assert(!os_initialized);
|
|
||||||
|
|
||||||
if (!oy.ExpectFirstPage(os))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
os_initialized = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
MPDOpusDecoder::ReadNextPage(OggSyncState &oy)
|
MPDOpusDecoder::ReadNextPage(OggSyncState &oy)
|
||||||
{
|
{
|
||||||
assert(os_initialized);
|
|
||||||
|
|
||||||
ogg_page page;
|
ogg_page page;
|
||||||
if (!oy.ExpectPage(page))
|
if (!oy.ExpectPage(page))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const auto page_serialno = ogg_page_serialno(&page);
|
const auto page_serialno = ogg_page_serialno(&page);
|
||||||
if (page_serialno != os.serialno)
|
if (page_serialno != os.GetSerialNo())
|
||||||
ogg_stream_reset_serialno(&os, page_serialno);
|
os.Reinitialize(page_serialno);
|
||||||
|
|
||||||
ogg_stream_pagein(&os, &page);
|
os.PageIn(page);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +141,7 @@ inline DecoderCommand
|
|||||||
MPDOpusDecoder::HandlePackets()
|
MPDOpusDecoder::HandlePackets()
|
||||||
{
|
{
|
||||||
ogg_packet packet;
|
ogg_packet packet;
|
||||||
while (ogg_stream_packetout(&os, &packet) == 1) {
|
while (os.PacketOut(packet) == 1) {
|
||||||
auto cmd = HandlePacket(packet);
|
auto cmd = HandlePacket(packet);
|
||||||
if (cmd != DecoderCommand::NONE)
|
if (cmd != DecoderCommand::NONE)
|
||||||
return cmd;
|
return cmd;
|
||||||
@@ -264,7 +247,7 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet)
|
|||||||
return DecoderCommand::STOP;
|
return DecoderCommand::STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
opus_serialno = os.serialno;
|
opus_serialno = os.GetSerialNo();
|
||||||
|
|
||||||
/* TODO: parse attributes from the OpusHead (sample rate,
|
/* TODO: parse attributes from the OpusHead (sample rate,
|
||||||
channels, ...) */
|
channels, ...) */
|
||||||
@@ -407,13 +390,15 @@ mpd_opus_stream_decode(Decoder &decoder,
|
|||||||
moved it */
|
moved it */
|
||||||
input_stream.LockRewind(IgnoreError());
|
input_stream.LockRewind(IgnoreError());
|
||||||
|
|
||||||
MPDOpusDecoder d(decoder, input_stream);
|
|
||||||
DecoderReader reader(decoder, input_stream);
|
DecoderReader reader(decoder, input_stream);
|
||||||
OggSyncState oy(reader);
|
OggSyncState oy(reader);
|
||||||
|
|
||||||
if (!d.ReadFirstPage(oy))
|
ogg_page page;
|
||||||
|
if (!oy.ExpectPage(page))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
MPDOpusDecoder d(decoder, input_stream, page);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto cmd = d.HandlePackets();
|
auto cmd = d.HandlePackets();
|
||||||
if (cmd == DecoderCommand::SEEK) {
|
if (cmd == DecoderCommand::SEEK) {
|
||||||
|
Reference in New Issue
Block a user