From 04f16811e1de827a0c90fabc0cae366ab9810035 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 16 Mar 2022 01:29:02 +0000 Subject: [PATCH] Feature: Report data from FLAC block STREAMINFO --- src/format_flac.c | 25 +++++++++++++++++++++++++ src/metadata_xiph.c | 13 +++++++++++++ src/metadata_xiph.h | 1 + 3 files changed, 39 insertions(+) diff --git a/src/format_flac.c b/src/format_flac.c index c88344bd..e8205420 100644 --- a/src/format_flac.c +++ b/src/format_flac.c @@ -127,11 +127,36 @@ static const char * flac_block_type_to_name(flac_block_type_t type) return ""; } +static void flac_handle_block_streaminfo(format_plugin_t *plugin, ogg_state_t *ogg_info, ogg_codec_t *codec, const flac_block_t *block) +{ + uint32_t raw; + uint32_t sample_rate; + uint32_t channels; + uint32_t bits; + + if (block->len != 34) { + ICECAST_LOG_ERROR("Can not parse FLAC header block STREAMINFO"); + return; + } + + raw = metadata_xiph_read_u32be_unaligned(block->data + 10); + sample_rate = ((raw >> 12) & 0xfffff) + 0; + channels = ((raw >> 9) & 0x7 ) + 1; + bits = ((raw >> 4) & 0x1F ) + 1; + + stats_event_args(ogg_info->mount, "audio_samplerate", "%ld", (long int)sample_rate); + stats_event_args(ogg_info->mount, "audio_channels", "%ld", (long int)channels); + stats_event_args(ogg_info->mount, "audio_bits", "%ld", (long int)bits); +} + static void flac_handle_block(format_plugin_t *plugin, ogg_state_t *ogg_info, ogg_codec_t *codec, const flac_block_t *block) { ICECAST_LOG_DEBUG("Found header of type %s%s with %zu bytes of data", flac_block_type_to_name(block->type), block->last ? "(last)" : "", block->len); switch (block->type) { + case FLAC_BLOCK_TYPE_STREAMINFO: + flac_handle_block_streaminfo(plugin, ogg_info, codec, block); + break; case FLAC_BLOCK_TYPE_VORBIS_COMMENT: vorbis_comment_clear(&plugin->vc); vorbis_comment_init(&plugin->vc); diff --git a/src/metadata_xiph.c b/src/metadata_xiph.c index beeec5b0..395f6542 100644 --- a/src/metadata_xiph.c +++ b/src/metadata_xiph.c @@ -18,6 +18,19 @@ #include "logging.h" #define CATMODULE "metadata-xiph" +uint32_t metadata_xiph_read_u32be_unaligned(const unsigned char *in) +{ + uint32_t ret = 0; + ret += in[0]; + ret <<= 8; + ret += in[1]; + ret <<= 8; + ret += in[2]; + ret <<= 8; + ret += in[3]; + return ret; +} + uint32_t metadata_xiph_read_u32le_unaligned(const unsigned char *in) { uint32_t ret = 0; diff --git a/src/metadata_xiph.h b/src/metadata_xiph.h index 3c1056b4..7127fdca 100644 --- a/src/metadata_xiph.h +++ b/src/metadata_xiph.h @@ -15,6 +15,7 @@ #include +uint32_t metadata_xiph_read_u32be_unaligned(const unsigned char *in); uint32_t metadata_xiph_read_u32le_unaligned(const unsigned char *in); /* returns true if parsing was successful, *vc must be in inited state before and will be in inited state after (even when false is returned) */