From 2f0dba0f20fbcd6bb3c75c475e952154e2ef44dc Mon Sep 17 00:00:00 2001
From: Ankith <[EMAIL REDACTED]>
Date: Sun, 22 Oct 2023 21:40:02 +0530
Subject: [PATCH] flac-in-ogg handling (#566)
- Fix flac-in-ogg detection
- Fix flac-in-ogg handling in libflac backend
---
src/codecs/music_flac.c | 56 +++++++++++++++++++++++++++++++++++------
src/music.c | 3 +++
2 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/src/codecs/music_flac.c b/src/codecs/music_flac.c
index 87f7c5f9..22ebdfd2 100644
--- a/src/codecs/music_flac.c
+++ b/src/codecs/music_flac.c
@@ -49,6 +49,17 @@ typedef struct {
FLAC__StreamDecoderMetadataCallback metadata_callback,
FLAC__StreamDecoderErrorCallback error_callback,
void *client_data);
+ FLAC__StreamDecoderInitStatus (*FLAC__stream_decoder_init_ogg_stream)(
+ FLAC__StreamDecoder *decoder,
+ FLAC__StreamDecoderReadCallback read_callback,
+ FLAC__StreamDecoderSeekCallback seek_callback,
+ FLAC__StreamDecoderTellCallback tell_callback,
+ FLAC__StreamDecoderLengthCallback length_callback,
+ FLAC__StreamDecoderEofCallback eof_callback,
+ FLAC__StreamDecoderWriteCallback write_callback,
+ FLAC__StreamDecoderMetadataCallback metadata_callback,
+ FLAC__StreamDecoderErrorCallback error_callback,
+ void *client_data);
FLAC__bool (*FLAC__stream_decoder_finish)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_flush)(FLAC__StreamDecoder *decoder);
FLAC__bool (*FLAC__stream_decoder_process_single)(
@@ -104,6 +115,17 @@ static int FLAC_Load(void)
FLAC__StreamDecoderMetadataCallback,
FLAC__StreamDecoderErrorCallback,
void *))
+ FUNCTION_LOADER(FLAC__stream_decoder_init_ogg_stream, FLAC__StreamDecoderInitStatus (*)(
+ FLAC__StreamDecoder *,
+ FLAC__StreamDecoderReadCallback,
+ FLAC__StreamDecoderSeekCallback,
+ FLAC__StreamDecoderTellCallback,
+ FLAC__StreamDecoderLengthCallback,
+ FLAC__StreamDecoderEofCallback,
+ FLAC__StreamDecoderWriteCallback,
+ FLAC__StreamDecoderMetadataCallback,
+ FLAC__StreamDecoderErrorCallback,
+ void *))
FUNCTION_LOADER(FLAC__stream_decoder_finish, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_flush, FLAC__bool (*)(FLAC__StreamDecoder *))
FUNCTION_LOADER(FLAC__stream_decoder_process_single, FLAC__bool (*)(FLAC__StreamDecoder *))
@@ -489,6 +511,14 @@ static void *FLAC_CreateFromRW(SDL_RWops *src, SDL_bool freesrc)
int init_stage = 0;
int was_error = 1;
FLAC__int64 full_length;
+ int is_ogg_flac;
+ Uint8 magic[4];
+ if (SDL_RWread(src, magic, 4) != 4) {
+ SDL_SetError("Couldn't read first 4 bytes of audio data");
+ return NULL;
+ }
+ SDL_RWseek(src, -4, SDL_RW_SEEK_CUR);
+ is_ogg_flac = (SDL_memcmp(magic, "OggS", 4) == 0);
music = (FLAC_Music *)SDL_calloc(1, sizeof(*music));
if (!music) {
@@ -500,17 +530,29 @@ static void *FLAC_CreateFromRW(SDL_RWops *src, SDL_bool freesrc)
music->flac_decoder = flac.FLAC__stream_decoder_new();
if (music->flac_decoder) {
+ FLAC__StreamDecoderInitStatus ret;
init_stage++; /* stage 1! */
flac.FLAC__stream_decoder_set_metadata_respond(music->flac_decoder,
FLAC__METADATA_TYPE_VORBIS_COMMENT);
- if (flac.FLAC__stream_decoder_init_stream(
- music->flac_decoder,
- flac_read_music_cb, flac_seek_music_cb,
- flac_tell_music_cb, flac_length_music_cb,
- flac_eof_music_cb, flac_write_music_cb,
- flac_metadata_music_cb, flac_error_music_cb,
- music) == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
+ if (is_ogg_flac) {
+ ret = flac.FLAC__stream_decoder_init_ogg_stream(
+ music->flac_decoder,
+ flac_read_music_cb, flac_seek_music_cb,
+ flac_tell_music_cb, flac_length_music_cb,
+ flac_eof_music_cb, flac_write_music_cb,
+ flac_metadata_music_cb, flac_error_music_cb,
+ music);
+ } else {
+ ret = flac.FLAC__stream_decoder_init_stream(
+ music->flac_decoder,
+ flac_read_music_cb, flac_seek_music_cb,
+ flac_tell_music_cb, flac_length_music_cb,
+ flac_eof_music_cb, flac_write_music_cb,
+ flac_metadata_music_cb, flac_error_music_cb,
+ music);
+ }
+ if (ret == FLAC__STREAM_DECODER_INIT_STATUS_OK) {
init_stage++; /* stage 2! */
if (flac.FLAC__stream_decoder_process_until_end_of_metadata(music->flac_decoder)) {
diff --git a/src/music.c b/src/music.c
index c295b793..68e92799 100644
--- a/src/music.c
+++ b/src/music.c
@@ -574,6 +574,9 @@ Mix_MusicType detect_music_type(SDL_RWops *src)
if (SDL_memcmp(magic, "OpusHead", 8) == 0) {
return MUS_OPUS;
}
+ if (magic[0] == 0x7F && SDL_memcmp(magic + 1, "FLAC", 4) == 0) {
+ return MUS_FLAC;
+ }
return MUS_OGG;
}