Changes made to mad plugin:
[vlc.git] / plugins / mad / mad_libmad.c
index 5f2a36b..5e0301a 100644 (file)
@@ -47,8 +47,8 @@
 enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
 {
     mad_adec_thread_t *p_mad_adec = (mad_adec_thread_t *) data;
-    size_t ReadSize, Remaining;
-    unsigned char      *ReadStart;
+    size_t            ReadSize, Remaining;
+    unsigned char     *ReadStart;
 
     if ( p_mad_adec->p_fifo->b_die == 1 ) {
         intf_ErrMsg( "mad_adec error: libmad_input stopping libmad decoder" );
@@ -65,35 +65,38 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
      */
     if ((p_libmad_stream->buffer==NULL) || (p_libmad_stream->error==MAD_ERROR_BUFLEN))
     {
-        /* libmad does not consume all the buffer it's given. Some
-         * datas, part of a truncated frame, is left unused at the
-         * end of the buffer. Those datas must be put back at the
-         * beginning of the buffer and taken in account for
-         * refilling the buffer. This means that the input buffer
-         * must be large enough to hold a complete frame at the
-         * highest observable bit-rate (currently 448 kb/s). XXX=XXX
-         * Is 2016 bytes the size of the largest frame?
-         * (448000*(1152/32000))/8
-         */
-        if(p_libmad_stream->next_frame!=NULL)
-        {
-            Remaining=p_libmad_stream->bufend-p_libmad_stream->next_frame;
-            memmove(p_mad_adec->buffer,p_libmad_stream->next_frame,Remaining);
-            ReadStart=p_mad_adec->buffer+Remaining;
-            ReadSize=(MAD_BUFFER_SIZE)-Remaining;
+       /* libmad does not consume all the buffer it's given. Some
+        * datas, part of a truncated frame, is left unused at the
+        * end of the buffer. Those datas must be put back at the
+        * beginning of the buffer and taken in account for
+        * refilling the buffer. This means that the input buffer
+        * must be large enough to hold a complete frame at the
+        * highest observable bit-rate (currently 448 kb/s). XXX=XXX
+        * Is 2016 bytes the size of the largest frame?
+        * (448000*(1152/32000))/8
+        */
+       if (p_libmad_stream->next_frame!=NULL)
+       {
+           Remaining=p_libmad_stream->bufend-p_libmad_stream->next_frame;
+           memmove(p_mad_adec->buffer,p_libmad_stream->next_frame,Remaining);
+           ReadStart=p_mad_adec->buffer+Remaining;
+           ReadSize=(MAD_BUFFER_SIZE)-Remaining;               
 
             /* Store time stamp of next frame */
             p_mad_adec->i_current_pts = p_mad_adec->i_next_pts;
             CurrentPTS( &p_mad_adec->bit_stream, &p_mad_adec->i_next_pts, NULL );
-        }
-        else
-        {
-            ReadSize=(MAD_BUFFER_SIZE);
-            ReadStart=p_mad_adec->buffer;
-            Remaining=0;
-            p_mad_adec->i_next_pts = 0;
+       }
+       else
+       {
+           ReadSize=(MAD_BUFFER_SIZE);
+           ReadStart=p_mad_adec->buffer;
+           Remaining=0;
+       
+           p_mad_adec->i_next_pts = 0;
             CurrentPTS( &p_mad_adec->bit_stream, &p_mad_adec->i_current_pts, NULL );
-        }
+       }
+       //intf_ErrMsg( "mad_adec debug: buffer size remaining [%d] and readsize [%d] total [%d]", 
+       //              Remaining, ReadSize, ReadSize+Remaining);
 
         /* Fill-in the buffer. If an error occurs print a message
          * and leave the decoding loop. If the end of stream is
@@ -132,13 +135,12 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
             return MAD_FLOW_IGNORE;
         }
 
-        /* Pipe the new buffer content to libmad's stream decoder facility.
-         * Libmad never copies the buffer, but just references it. So keep it in
-         * mad_adec_thread_t structure.
-         */
-        mad_stream_buffer(p_libmad_stream,(unsigned char*) &p_mad_adec->buffer,
-                          MAD_BUFFER_SIZE);
-        p_libmad_stream->error=0;
+       /* Pipe the new buffer content to libmad's stream decoder facility.
+         * Libmad never copies the buffer, but just references it. So keep it in 
+        * mad_adec_thread_t structure.
+        */
+       mad_stream_buffer(p_libmad_stream,(unsigned char*) &p_mad_adec->buffer,MAD_BUFFER_SIZE);
+       p_libmad_stream->error=0;
     }
 
     return MAD_FLOW_CONTINUE;
@@ -157,7 +159,7 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
  *   intf_DbgMsg( "mad_adec: libmad_header bitrate %d", p_libmad_header->bitrate);     
  *
  *   p_mad_adec->p_aout_fifo->l_rate = p_libmad_header->samplerate;
- *   mad_timer_add(&p_mad_adec->libmad_timer,p_libmad_header->duration); 
+ *   mad_timer_add(&p_mad_adec->libmad_timer,p_libmad_header->duration);
  *
  *   return MAD_FLOW_CONTINUE;
  *}
@@ -259,12 +261,12 @@ static __inline__ signed int audio_linear_dither(unsigned int bits, mad_fixed_t
     /* scale */
     return output >> scalebits;
 }
-#endif
+#else
 
 /*****************************************************************************
  * s24_to_s16_pcm: Scale a 24 bit pcm sample to a 16 bit pcm sample.
  *****************************************************************************/
-static __inline__ mad_fixed_t s24_to_s16_pcm(mad_fixed_t sample)
+static __inline__ mad_fixed_t (mad_fixed_t sample)
 {
   /* round */
   sample += (1L << (MAD_F_FRACBITS - 16));
@@ -278,6 +280,7 @@ static __inline__ mad_fixed_t s24_to_s16_pcm(mad_fixed_t sample)
   /* quantize */
   return sample >> (MAD_F_FRACBITS + 1 - 16);
 }
+#endif
 
 /*****************************************************************************
  * libmad_ouput: this function is called just after the frame is decoded
@@ -294,10 +297,12 @@ enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header
     static struct audio_dither dither;
 #endif
 
-    /* Creating the audio output fifo */
+    /* Creating the audio output fifo.
+     * Assume the samplerate and nr of channels from the first decoded frame is right for the entire audio track.
+     */
     if (p_mad_adec->p_aout_fifo==NULL)
     {
-       p_mad_adec->p_aout_fifo = aout_CreateFifo(  
+       p_mad_adec->p_aout_fifo = aout_CreateFifo(
                AOUT_ADEC_STEREO_FIFO,          /* fifo type */
                p_libmad_pcm->channels,         /* nr. of channels */
                p_libmad_pcm->samplerate,       /* frame rate in Hz ?*/
@@ -312,28 +317,16 @@ enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header
 
         intf_ErrMsg("mad_adec debug: in libmad_output aout fifo created");
     }
-    else
-    {
-        p_mad_adec->p_aout_fifo->l_rate = p_libmad_pcm->samplerate;
-    }
 
-/* Some frames are nog quite right. Why ??? I do not know. Probably syncing and CRC errors ??
- * Leaving those frames out futher removes the jitter in the sound and makes it more fluent.
- * Still I am missing something, because it is not completely fluent.
- */
-    if ((p_mad_adec->libmad_decoder->sync->stream.error==MAD_ERROR_BADCRC) ||
-       (p_mad_adec->libmad_decoder->sync->stream.error==MAD_ERROR_BADBITRATE) ||
-       (p_mad_adec->libmad_decoder->sync->stream.error==MAD_ERROR_BADSCALEFACTOR)
-       ) {
-//     intf_ErrMsg( "LIBMAD_OUTPUT: nr of channels [%d], samplerate in Hz [%d,%d], sample size [%d], error_code [%0x]",
-//              p_libmad_pcm->channels, p_libmad_pcm->samplerate, p_libmad_header->samplerate,
-//                      p_libmad_pcm->length, p_mad_adec->libmad_decoder->sync->stream.error);
-//      PrintFrameInfo(&p_libmad_header);
-       return MAD_FLOW_IGNORE;
+    /* Set timestamp to synchronize audio and video decoder fifo's */
+    if (p_mad_adec->p_aout_fifo->l_rate != p_libmad_pcm->samplerate)
+    {
+       intf_ErrMsg( "mad_adec: libmad_output samplerate is changing from [%d] Hz to [%d] Hz, sample size [%d], error_code [%0x]",
+                   p_mad_adec->p_aout_fifo->l_rate, p_libmad_pcm->samplerate,
+                    p_libmad_pcm->length, p_mad_adec->libmad_decoder->sync->stream.error);
+       p_mad_adec->p_aout_fifo->l_rate = p_libmad_pcm->samplerate;
     }
 
-    /* Set timestamp to synchronize audio and video decoder fifo's */
-    p_mad_adec->p_aout_fifo->l_rate = p_libmad_header->samplerate;
     if( p_mad_adec->i_current_pts )
     {
         p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->l_end_frame]
@@ -437,7 +430,7 @@ enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struc
         result = MAD_FLOW_CONTINUE;
         break;
     case MAD_ERROR_BADSAMPLERATE: /* reserved sample frequency value */
-            intf_ErrMsg("libmad error: reserved sample frequency value");
+        intf_ErrMsg("libmad error: reserved sample frequency value");
         result = MAD_FLOW_CONTINUE;
         break;
     case MAD_ERROR_BADEMPHASIS:     /* reserved emphasis value */
@@ -498,8 +491,8 @@ enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struc
         break;
     }
     
-    //return (MAD_RECOVERABLE(p_libmad_stream->error)? result: MAD_FLOW_STOP);
-    return (MAD_FLOW_CONTINUE);
+    return (MAD_RECOVERABLE(p_libmad_stream->error)? result: MAD_FLOW_STOP);
+    //return (MAD_FLOW_CONTINUE);
 }
 
 /*****************************************************************************