Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/helpers/packet_decoder_mp3_common.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/packet_decoder_mp3_common.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,84 @@ +#pragma once +#include <SDK/packet_decoder.h> +/* +Helper code with common MP3 packet_decoder functionality. Primarily meant for foo_input_std-internal use. +*/ + +class packet_decoder_mp3_common : public packet_decoder { +public: + static unsigned parseDecoderSetup( const GUID & p_owner,t_size p_param1,const void * p_param2,t_size p_param2size ); + + static unsigned layer_from_frame(const void *, size_t); + + static unsigned get_max_frame_dependency_() {return 10;} + static double get_max_frame_dependency_time_() {return 10.0 * 1152.0 / 32000.0;} +}; + + +template<typename impl_t> +class packet_decoder_mp3 : public packet_decoder +{ + impl_t m_decoder; + unsigned m_layer; + + void init(unsigned p_layer) { + m_layer = p_layer; + m_decoder.reset_after_seek(); + } + + bool m_MP4fixes; + +public: + packet_decoder_mp3() : m_layer(0), m_MP4fixes() + { + } + + ~packet_decoder_mp3() + { + } + + t_size set_stream_property(const GUID & p_type, t_size p_param1, const void * p_param2, t_size p_param2size) { + return m_decoder.set_stream_property(p_type, p_param1, p_param2, p_param2size); + } + + void get_info(file_info & p_info) + { + switch (m_layer) + { + case 1: p_info.info_set("codec", "MP1"); break; + case 2: p_info.info_set("codec", "MP2"); break; + case 3: p_info.info_set("codec", "MP3"); break; + default: + throw exception_io_data(); + } + p_info.info_set("encoding", "lossy"); + } + + unsigned get_max_frame_dependency() { return 10; } + double get_max_frame_dependency_time() { return 10.0 * 1152.0 / 32000.0; } + + static bool g_is_our_setup(const GUID & p_owner, t_size p_param1, const void * p_param2, t_size p_param2size) { + return packet_decoder_mp3_common::parseDecoderSetup(p_owner, p_param1, p_param2, p_param2size) != 0; + } + + void open(const GUID & p_owner, bool p_decode, t_size p_param1, const void * p_param2, t_size p_param2size, abort_callback & p_abort) + { + m_MP4fixes = (p_owner == owner_MP4); + unsigned layer = packet_decoder_mp3_common::parseDecoderSetup(p_owner, p_param1, p_param2, p_param2size); + if (layer == 0) throw exception_io_data(); + init(layer); + } + + void reset_after_seek() { + m_decoder.reset_after_seek(); + } + + void decode(const void * p_buffer, t_size p_bytes, audio_chunk & p_chunk, abort_callback & p_abort) { + m_decoder.decode(p_buffer, p_bytes, p_chunk, p_abort); + } + + bool analyze_first_frame_supported() { return m_MP4fixes; } + void analyze_first_frame(const void * p_buffer, t_size p_bytes, abort_callback & p_abort) { + m_layer = packet_decoder_mp3_common::layer_from_frame(p_buffer, p_bytes); + } +};
