#pragma once /* 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 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); } };