@@ -670,135 +670,6 @@ class MultiStreamingDecoder : public StreamingDecoder {
670
670
void setMimeSource (MimeSource& mimeSource) { p_mime_source = &mimeSource; }
671
671
672
672
protected:
673
- /* *
674
- * @brief Simple buffered stream that prefixes buffered data before reading
675
- * from the main stream
676
- *
677
- * This internal helper class creates a virtual stream that first serves data
678
- * from a buffer (used for format detection), then seamlessly continues
679
- * reading from the main input stream. This ensures that data used for MIME
680
- * detection is not lost and is available to the selected decoder.
681
- */
682
- class BufferedPrefixStream : public Stream {
683
- public:
684
- /* *
685
- * @brief Sets the main stream to read from after buffer is exhausted
686
- *
687
- * @param stream The main input stream
688
- */
689
- void setStream (Stream& stream) { p_stream = &stream; }
690
-
691
- /* *
692
- * @brief Sets the buffer data to serve first
693
- *
694
- * @param data Pointer to buffer data
695
- * @param len Length of buffer data
696
- */
697
- void setBuffer (uint8_t * data, size_t len) {
698
- buffer_data = data;
699
- buffer_size = len;
700
- buffer_pos = 0 ;
701
- has_buffer = true ;
702
- }
703
-
704
- /* *
705
- * @brief Returns number of bytes available for reading
706
- *
707
- * @return Total bytes available from buffer and main stream
708
- */
709
- int available () override {
710
- int result = 0 ;
711
- if (has_buffer && buffer_pos < buffer_size) {
712
- result += buffer_size - buffer_pos;
713
- }
714
- if (p_stream != nullptr ) {
715
- result += p_stream->available ();
716
- }
717
- return result;
718
- }
719
-
720
- /* *
721
- * @brief Reads a single byte
722
- *
723
- * Reads from buffer first, then from main stream when buffer is exhausted.
724
- *
725
- * @return Byte value or -1 if no data available
726
- */
727
- int read () override {
728
- if (has_buffer && buffer_pos < buffer_size) {
729
- return buffer_data[buffer_pos++];
730
- }
731
- if (p_stream != nullptr ) {
732
- return p_stream->read ();
733
- }
734
- return -1 ;
735
- }
736
-
737
- /* *
738
- * @brief Reads multiple bytes into a buffer
739
- *
740
- * Reads from internal buffer first, then continues with main stream.
741
- *
742
- * @param data Buffer to store read data
743
- * @param len Maximum number of bytes to read
744
- * @return Number of bytes actually read
745
- */
746
- size_t readBytes (uint8_t * data, size_t len) override {
747
- size_t total_read = 0 ;
748
-
749
- // First read from buffer if available
750
- if (has_buffer && buffer_pos < buffer_size) {
751
- size_t buffer_available = buffer_size - buffer_pos;
752
- size_t from_buffer = min (len, buffer_available);
753
- memcpy (data, buffer_data + buffer_pos, from_buffer);
754
- buffer_pos += from_buffer;
755
- total_read += from_buffer;
756
- data += from_buffer;
757
- len -= from_buffer;
758
-
759
- // If we consumed all buffer data, mark as done
760
- if (buffer_pos >= buffer_size) {
761
- has_buffer = false ;
762
- }
763
- }
764
-
765
- // Then read remaining from stream
766
- if (len > 0 && p_stream != nullptr ) {
767
- total_read += p_stream->readBytes (data, len);
768
- }
769
-
770
- return total_read;
771
- }
772
-
773
- /* *
774
- * @brief Write operation (not supported for input stream)
775
- *
776
- * @return 0 (write not supported)
777
- */
778
- size_t write (uint8_t ) override { return 0 ; } // Not used for input
779
-
780
- /* *
781
- * @brief Peeks at the next byte without consuming it
782
- *
783
- * @return Next byte value or -1 if no data available
784
- */
785
- int peek () override {
786
- if (has_buffer && buffer_pos < buffer_size) {
787
- return buffer_data[buffer_pos];
788
- }
789
- if (p_stream != nullptr ) {
790
- return p_stream->peek ();
791
- }
792
- return -1 ;
793
- }
794
-
795
- protected:
796
- Stream* p_stream = nullptr ; // /< Main input stream
797
- uint8_t * buffer_data = nullptr ; // /< Buffer data pointer
798
- size_t buffer_size = 0 ; // /< Size of buffer data
799
- size_t buffer_pos = 0 ; // /< Current position in buffer
800
- bool has_buffer = false ; // /< Whether buffer has data to serve
801
- };
802
673
803
674
/* *
804
675
* @brief Information about a registered decoder
@@ -829,8 +700,8 @@ class MultiStreamingDecoder : public StreamingDecoder {
829
700
Vector<StreamingDecoderAdapter*> adapters{
830
701
0 }; // /< Collection of internally created adapters
831
702
MimeDetector mime_detector; // /< MIME type detection engine
832
- BufferedPrefixStream
833
- buffered_stream; // /< Buffered stream for data preservation
703
+ BufferedStream
704
+ buffered_stream{DEFAULT_BUFFER_SIZE} ; // /< Buffered stream for data preservation
834
705
Vector<uint8_t > detection_buffer{0 }; // /< Buffer for format detection data
835
706
bool is_first = true ; // /< Flag for first copy() call
836
707
const char * selected_mime = nullptr ; // /< MIME type that was selected
@@ -882,17 +753,12 @@ class MultiStreamingDecoder : public StreamingDecoder {
882
753
883
754
// Allocate buffer for MIME detection sample (80 bytes is typically sufficient
884
755
// for most audio format headers to be identified)
885
- detection_buffer.resize (80 );
886
- size_t bytesRead = readBytes (detection_buffer.data (), detection_buffer.size ());
756
+ detection_buffer.resize (160 );
757
+ size_t bytesRead = buffered_stream. peekBytes (detection_buffer.data (), detection_buffer.size ());
887
758
888
759
// If no data is available, we cannot proceed with detection
889
760
if (bytesRead == 0 ) return false ;
890
761
891
- // Preserve the detection data for the selected decoder by setting up
892
- // the buffered stream. This ensures the data used for detection
893
- // is not lost and will be available to the decoder
894
- buffered_stream.setBuffer (detection_buffer.data (), bytesRead);
895
-
896
762
// Feed the sample data to the MIME detector for format analysis
897
763
// The detector examines file headers, magic numbers, etc.
898
764
mime_detector.write (detection_buffer.data (), bytesRead);
0 commit comments