decoder/mad: make enums strictly-typed
This commit is contained in:
parent
97e6ea57c4
commit
22a9e866bc
@ -49,17 +49,17 @@
|
|||||||
|
|
||||||
static constexpr unsigned long FRAMES_CUSHION = 2000;
|
static constexpr unsigned long FRAMES_CUSHION = 2000;
|
||||||
|
|
||||||
enum mp3_action {
|
enum class MadDecoderAction {
|
||||||
DECODE_SKIP = -3,
|
SKIP,
|
||||||
DECODE_BREAK = -2,
|
BREAK,
|
||||||
DECODE_CONT = -1,
|
CONT,
|
||||||
DECODE_OK = 0
|
OK
|
||||||
};
|
};
|
||||||
|
|
||||||
enum muteframe {
|
enum class MadDecoderMuteFrame {
|
||||||
MUTEFRAME_NONE,
|
NONE,
|
||||||
MUTEFRAME_SKIP,
|
SKIP,
|
||||||
MUTEFRAME_SEEK
|
SEEK
|
||||||
};
|
};
|
||||||
|
|
||||||
/* the number of samples of silence the decoder inserts at start */
|
/* the number of samples of silence the decoder inserts at start */
|
||||||
@ -129,7 +129,7 @@ struct MadDecoder {
|
|||||||
SignedSongTime total_time;
|
SignedSongTime total_time;
|
||||||
SongTime elapsed_time;
|
SongTime elapsed_time;
|
||||||
SongTime seek_time;
|
SongTime seek_time;
|
||||||
enum muteframe mute_frame = MUTEFRAME_NONE;
|
MadDecoderMuteFrame mute_frame = MadDecoderMuteFrame::NONE;
|
||||||
long *frame_offsets = nullptr;
|
long *frame_offsets = nullptr;
|
||||||
mad_timer_t *times = nullptr;
|
mad_timer_t *times = nullptr;
|
||||||
unsigned long highest_frame = 0;
|
unsigned long highest_frame = 0;
|
||||||
@ -153,8 +153,8 @@ struct MadDecoder {
|
|||||||
bool Seek(long offset);
|
bool Seek(long offset);
|
||||||
bool FillBuffer();
|
bool FillBuffer();
|
||||||
void ParseId3(size_t tagsize, Tag *tag);
|
void ParseId3(size_t tagsize, Tag *tag);
|
||||||
enum mp3_action DecodeNextFrameHeader(Tag *tag);
|
MadDecoderAction DecodeNextFrameHeader(Tag *tag);
|
||||||
enum mp3_action DecodeNextFrame();
|
MadDecoderAction DecodeNextFrame();
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
offset_type ThisFrameOffset() const noexcept;
|
offset_type ThisFrameOffset() const noexcept;
|
||||||
@ -364,26 +364,26 @@ id3_tag_query(const void *p0, size_t length)
|
|||||||
}
|
}
|
||||||
#endif /* !ENABLE_ID3TAG */
|
#endif /* !ENABLE_ID3TAG */
|
||||||
|
|
||||||
static enum mp3_action
|
static MadDecoderAction
|
||||||
RecoverFrameError(struct mad_stream &stream)
|
RecoverFrameError(struct mad_stream &stream)
|
||||||
{
|
{
|
||||||
if (MAD_RECOVERABLE(stream.error))
|
if (MAD_RECOVERABLE(stream.error))
|
||||||
return DECODE_SKIP;
|
return MadDecoderAction::SKIP;
|
||||||
else if (stream.error == MAD_ERROR_BUFLEN)
|
else if (stream.error == MAD_ERROR_BUFLEN)
|
||||||
return DECODE_CONT;
|
return MadDecoderAction::CONT;
|
||||||
|
|
||||||
FormatWarning(mad_domain,
|
FormatWarning(mad_domain,
|
||||||
"unrecoverable frame level error: %s",
|
"unrecoverable frame level error: %s",
|
||||||
mad_stream_errorstr(&stream));
|
mad_stream_errorstr(&stream));
|
||||||
return DECODE_BREAK;
|
return MadDecoderAction::BREAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mp3_action
|
MadDecoderAction
|
||||||
MadDecoder::DecodeNextFrameHeader(Tag *tag)
|
MadDecoder::DecodeNextFrameHeader(Tag *tag)
|
||||||
{
|
{
|
||||||
if ((stream.buffer == nullptr || stream.error == MAD_ERROR_BUFLEN) &&
|
if ((stream.buffer == nullptr || stream.error == MAD_ERROR_BUFLEN) &&
|
||||||
!FillBuffer())
|
!FillBuffer())
|
||||||
return DECODE_BREAK;
|
return MadDecoderAction::BREAK;
|
||||||
|
|
||||||
if (mad_header_decode(&frame.header, &stream)) {
|
if (mad_header_decode(&frame.header, &stream)) {
|
||||||
if (stream.error == MAD_ERROR_LOSTSYNC && stream.this_frame) {
|
if (stream.error == MAD_ERROR_LOSTSYNC && stream.this_frame) {
|
||||||
@ -393,7 +393,7 @@ MadDecoder::DecodeNextFrameHeader(Tag *tag)
|
|||||||
|
|
||||||
if (tagsize > 0) {
|
if (tagsize > 0) {
|
||||||
ParseId3((size_t)tagsize, tag);
|
ParseId3((size_t)tagsize, tag);
|
||||||
return DECODE_CONT;
|
return MadDecoderAction::CONT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,24 +404,24 @@ MadDecoder::DecodeNextFrameHeader(Tag *tag)
|
|||||||
if (layer == (mad_layer)0) {
|
if (layer == (mad_layer)0) {
|
||||||
if (new_layer != MAD_LAYER_II && new_layer != MAD_LAYER_III) {
|
if (new_layer != MAD_LAYER_II && new_layer != MAD_LAYER_III) {
|
||||||
/* Only layer 2 and 3 have been tested to work */
|
/* Only layer 2 and 3 have been tested to work */
|
||||||
return DECODE_SKIP;
|
return MadDecoderAction::SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer = new_layer;
|
layer = new_layer;
|
||||||
} else if (new_layer != layer) {
|
} else if (new_layer != layer) {
|
||||||
/* Don't decode frames with a different layer than the first */
|
/* Don't decode frames with a different layer than the first */
|
||||||
return DECODE_SKIP;
|
return MadDecoderAction::SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DECODE_OK;
|
return MadDecoderAction::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mp3_action
|
MadDecoderAction
|
||||||
MadDecoder::DecodeNextFrame()
|
MadDecoder::DecodeNextFrame()
|
||||||
{
|
{
|
||||||
if ((stream.buffer == nullptr || stream.error == MAD_ERROR_BUFLEN) &&
|
if ((stream.buffer == nullptr || stream.error == MAD_ERROR_BUFLEN) &&
|
||||||
!FillBuffer())
|
!FillBuffer())
|
||||||
return DECODE_BREAK;
|
return MadDecoderAction::BREAK;
|
||||||
|
|
||||||
if (mad_frame_decode(&frame, &stream)) {
|
if (mad_frame_decode(&frame, &stream)) {
|
||||||
if (stream.error == MAD_ERROR_LOSTSYNC) {
|
if (stream.error == MAD_ERROR_LOSTSYNC) {
|
||||||
@ -430,14 +430,14 @@ MadDecoder::DecodeNextFrame()
|
|||||||
stream.this_frame);
|
stream.this_frame);
|
||||||
if (tagsize > 0) {
|
if (tagsize > 0) {
|
||||||
mad_stream_skip(&stream, tagsize);
|
mad_stream_skip(&stream, tagsize);
|
||||||
return DECODE_CONT;
|
return MadDecoderAction::CONT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RecoverFrameError(stream);
|
return RecoverFrameError(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DECODE_OK;
|
return MadDecoderAction::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xing stuff stolen from alsaplayer, and heavily modified by jat */
|
/* xing stuff stolen from alsaplayer, and heavily modified by jat */
|
||||||
@ -699,20 +699,20 @@ MadDecoder::DecodeFirstFrame(Tag *tag)
|
|||||||
struct xing xing;
|
struct xing xing;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
enum mp3_action ret;
|
MadDecoderAction ret;
|
||||||
do {
|
do {
|
||||||
ret = DecodeNextFrameHeader(tag);
|
ret = DecodeNextFrameHeader(tag);
|
||||||
} while (ret == DECODE_CONT);
|
} while (ret == MadDecoderAction::CONT);
|
||||||
if (ret == DECODE_BREAK)
|
if (ret == MadDecoderAction::BREAK)
|
||||||
return false;
|
return false;
|
||||||
if (ret == DECODE_SKIP) continue;
|
if (ret == MadDecoderAction::SKIP) continue;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = DecodeNextFrame();
|
ret = DecodeNextFrame();
|
||||||
} while (ret == DECODE_CONT);
|
} while (ret == MadDecoderAction::CONT);
|
||||||
if (ret == DECODE_BREAK)
|
if (ret == MadDecoderAction::BREAK)
|
||||||
return false;
|
return false;
|
||||||
if (ret == DECODE_OK) break;
|
if (ret == MadDecoderAction::OK) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mad_bitptr ptr = stream.anc_ptr;
|
struct mad_bitptr ptr = stream.anc_ptr;
|
||||||
@ -724,7 +724,7 @@ MadDecoder::DecodeFirstFrame(Tag *tag)
|
|||||||
* if an xing tag exists, use that!
|
* if an xing tag exists, use that!
|
||||||
*/
|
*/
|
||||||
if (parse_xing(&xing, &ptr, &bitlen)) {
|
if (parse_xing(&xing, &ptr, &bitlen)) {
|
||||||
mute_frame = MUTEFRAME_SKIP;
|
mute_frame = MadDecoderMuteFrame::SKIP;
|
||||||
|
|
||||||
if ((xing.flags & XING_FRAMES) && xing.frames) {
|
if ((xing.flags & XING_FRAMES) && xing.frames) {
|
||||||
mad_timer_t duration = frame.header.duration;
|
mad_timer_t duration = frame.header.duration;
|
||||||
@ -906,14 +906,14 @@ MadDecoder::Read()
|
|||||||
switch (mute_frame) {
|
switch (mute_frame) {
|
||||||
DecoderCommand cmd;
|
DecoderCommand cmd;
|
||||||
|
|
||||||
case MUTEFRAME_SKIP:
|
case MadDecoderMuteFrame::SKIP:
|
||||||
mute_frame = MUTEFRAME_NONE;
|
mute_frame = MadDecoderMuteFrame::NONE;
|
||||||
break;
|
break;
|
||||||
case MUTEFRAME_SEEK:
|
case MadDecoderMuteFrame::SEEK:
|
||||||
if (elapsed_time >= seek_time)
|
if (elapsed_time >= seek_time)
|
||||||
mute_frame = MUTEFRAME_NONE;
|
mute_frame = MadDecoderMuteFrame::NONE;
|
||||||
break;
|
break;
|
||||||
case MUTEFRAME_NONE:
|
case MadDecoderMuteFrame::NONE:
|
||||||
cmd = SyncAndSend();
|
cmd = SyncAndSend();
|
||||||
if (cmd == DecoderCommand::SEEK) {
|
if (cmd == DecoderCommand::SEEK) {
|
||||||
assert(input_stream.IsSeekable());
|
assert(input_stream.IsSeekable());
|
||||||
@ -928,7 +928,7 @@ MadDecoder::Read()
|
|||||||
client->SeekError();
|
client->SeekError();
|
||||||
} else {
|
} else {
|
||||||
seek_time = t;
|
seek_time = t;
|
||||||
mute_frame = MUTEFRAME_SEEK;
|
mute_frame = MadDecoderMuteFrame::SEEK;
|
||||||
client->CommandFinished();
|
client->CommandFinished();
|
||||||
}
|
}
|
||||||
} else if (cmd != DecoderCommand::NONE)
|
} else if (cmd != DecoderCommand::NONE)
|
||||||
@ -936,7 +936,7 @@ MadDecoder::Read()
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
enum mp3_action ret;
|
MadDecoderAction ret;
|
||||||
do {
|
do {
|
||||||
Tag tag;
|
Tag tag;
|
||||||
|
|
||||||
@ -945,21 +945,21 @@ MadDecoder::Read()
|
|||||||
if (!tag.IsEmpty())
|
if (!tag.IsEmpty())
|
||||||
client->SubmitTag(input_stream,
|
client->SubmitTag(input_stream,
|
||||||
std::move(tag));
|
std::move(tag));
|
||||||
} while (ret == DECODE_CONT);
|
} while (ret == MadDecoderAction::CONT);
|
||||||
if (ret == DECODE_BREAK)
|
if (ret == MadDecoderAction::BREAK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const bool skip = ret == DECODE_SKIP;
|
const bool skip = ret == MadDecoderAction::SKIP;
|
||||||
|
|
||||||
if (mute_frame == MUTEFRAME_NONE) {
|
if (mute_frame == MadDecoderMuteFrame::NONE) {
|
||||||
do {
|
do {
|
||||||
ret = DecodeNextFrame();
|
ret = DecodeNextFrame();
|
||||||
} while (ret == DECODE_CONT);
|
} while (ret == MadDecoderAction::CONT);
|
||||||
if (ret == DECODE_BREAK)
|
if (ret == MadDecoderAction::BREAK)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skip && ret == DECODE_OK)
|
if (!skip && ret == MadDecoderAction::OK)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user