enum mad_flow libmad_input( void *p_data, struct mad_stream *p_stream )
{
mad_adec_thread_t * p_dec = (mad_adec_thread_t *) p_data;
- size_t i_wanted, i_left;
+ size_t i_wanted, i_left, i_current;
if ( p_dec->p_fifo->b_die )
{
* (448000*(1152/32000))/8 */
if( p_stream->next_frame )
{
- i_left = p_stream->bufend - p_stream->next_frame;
+ i_left = p_stream->bufend - p_stream->next_frame;
+ i_current = p_stream->next_frame - p_dec->buffer;
if( p_dec->buffer != p_stream->next_frame )
{
memcpy( p_dec->buffer, p_stream->next_frame, i_left );
i_wanted = MAD_BUFFER_MDLEN - i_left;
/* Store timestamp for next frame */
- p_dec->i_next_pts = p_dec->p_fifo->p_first->i_pts;
+ if ( ( p_stream->next_frame == p_dec->buffer ) ||
+ ( i_current >= i_left * ( ( i_current / ( MAD_BUFFER_MDLEN - i_current ) ) + 1 ) )
+ )
+ {
+ p_dec->i_next_pts = p_dec->bit_stream.p_pes->i_pts;
+ }
+ else
+ {
+ /* p_dec->bit_stream.p_pes->i_pts != p_dec->i_next_pts */
+ p_dec->i_next_pts = 0;
+ }
}
else
{
i_left = 0;
/* Store timestamp for this frame */
- p_dec->i_current_pts = p_dec->p_fifo->p_first->i_pts;
+ p_dec->i_current_pts = p_dec->bit_stream.p_pes->i_pts;
}
/* Fill-in the buffer. If an error occurs print a message and leave
* the decoding loop. If the end of stream is reached we also leave
* the loop but the return status is left untouched. */
- if( i_wanted > p_dec->p_data->p_payload_end
- - p_dec->p_data->p_payload_start )
+ if( i_wanted > (size_t)(p_dec->bit_stream.p_data->p_payload_end
+ - p_dec->bit_stream.p_data->p_payload_start) )
{
- i_wanted = p_dec->p_data->p_payload_end
- - p_dec->p_data->p_payload_start;
+ i_wanted = p_dec->bit_stream.p_data->p_payload_end
+ - p_dec->bit_stream.p_data->p_payload_start;
memcpy( p_dec->buffer + i_left,
- p_dec->p_data->p_payload_start, i_wanted );
- NextDataPacket( p_dec->p_fifo, &p_dec->p_data );
+ p_dec->bit_stream.p_data->p_payload_start, i_wanted );
+ NextDataPacket( p_dec->p_fifo, &p_dec->bit_stream );
+ /* No need to check that p_dec->bit_stream->p_data is valid
+ * since we check later on for b_die and b_error */
}
else
{
memcpy( p_dec->buffer + i_left,
- p_dec->p_data->p_payload_start, i_wanted );
- p_dec->p_data->p_payload_start += i_wanted;
+ p_dec->bit_stream.p_data->p_payload_start, i_wanted );
+ p_dec->bit_stream.p_data->p_payload_start += i_wanted;
}
if ( p_dec->p_fifo->b_die )
aout_buffer_t * p_buffer;
mad_fixed_t const * p_left = p_pcm->samples[0];
mad_fixed_t const * p_right = p_pcm->samples[1];
- register int i_samples = p_pcm->length;
+ unsigned int i_samples = p_pcm->length;
mad_fixed_t * p_samples;
+ unsigned int i_channels = (p_pcm->channels == 2) ?
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT :
+ AOUT_CHAN_CENTER;
/* 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_dec->p_aout_input != NULL) &&
- (p_dec->output_format.i_rate != p_pcm->samplerate) )
+ (p_dec->output_format.i_rate != p_pcm->samplerate
+ || p_dec->output_format.i_physical_channels != i_channels) )
{
/* Parameters changed - this should not happen. */
- aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
+ aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
p_dec->p_aout_input = NULL;
}
if( p_dec->p_aout_input == NULL )
{
p_dec->output_format.i_rate = p_pcm->samplerate;
- /* p_dec->output_format.i_channels = p_pcm->channels; */
+ p_dec->output_format.i_physical_channels = i_channels;
+ p_dec->output_format.i_original_channels = i_channels;
aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
- p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
- &p_dec->p_aout,
- &p_dec->output_format );
+ p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
+ &p_dec->p_aout,
+ &p_dec->output_format );
if ( p_dec->p_aout_input == NULL )
{
return MAD_FLOW_CONTINUE;
}
- p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input, i_samples );
+ p_buffer = aout_DecNewBuffer( p_dec->p_aout, p_dec->p_aout_input, i_samples );
if ( p_buffer == NULL )
{
*p_samples++ = *p_right++;
}
break;
+
case 1:
- while( i_samples-- )
- {
- *p_samples++ = *p_left;
- *p_samples++ = *p_left++;
- }
+ p_dec->p_fifo->p_vlc->pf_memcpy( p_samples, p_left,
+ i_samples * sizeof(mad_fixed_t) );
break;
+
default:
msg_Err( p_dec->p_fifo, "cannot interleave %i channels",
p_pcm->channels );
}
- aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
+ aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
return MAD_FLOW_CONTINUE;
}
/*****************************************************************************
* libmad_error: this function is called when an error occurs during decoding
*****************************************************************************/
-enum mad_flow libmad_error( void *data, struct mad_stream *p_libmad_stream,
+enum mad_flow libmad_error( void *p_data, struct mad_stream *p_libmad_stream,
struct mad_frame *p_libmad_frame )
{
- mad_adec_thread_t *p_dec = (mad_adec_thread_t *) data;
- enum mad_flow result = MAD_FLOW_CONTINUE;
+ mad_adec_thread_t *p_dec = (mad_adec_thread_t *) p_data;
+ enum mad_flow result;
+ struct mad_pcm *p_pcm;
switch (p_libmad_stream->error)
{
+
+ case MAD_ERROR_BADDATAPTR: /* bad main_data_begin pointer */
+ msg_Warn( p_dec->p_fifo, "lost synchronization" );
+
+ if( p_dec->output_format.i_rate &&
+ p_dec->output_format.i_physical_channels )
+ {
+ p_pcm = malloc( sizeof(struct mad_pcm) );
+ memset( p_pcm, 0, sizeof(struct mad_pcm) );
+ p_pcm->length = 32 * MAD_NSBSAMPLES( &p_libmad_frame->header );
+ p_pcm->channels = ( p_dec->output_format.i_physical_channels ==
+ AOUT_CHAN_CENTER ) ? 1 : 2;
+ p_pcm->samplerate = p_dec->output_format.i_rate;
+ libmad_output( p_data, NULL, p_pcm );
+ free( p_pcm );
+ }
+ result = MAD_FLOW_CONTINUE;
+ break;
+
+ default:
+ result = MAD_FLOW_CONTINUE;
+ break;
+
+#if 0
case MAD_ERROR_BUFLEN: /* input buffer too small (or EOF) */
msg_Err( p_dec->p_fifo, "input buffer too small (or EOF)" );
result = MAD_FLOW_CONTINUE;
break;
case MAD_ERROR_LOSTSYNC: /* lost synchronization */
msg_Err( p_dec->p_fifo, "lost synchronization" );
- mad_stream_sync(p_libmad_stream);
result = MAD_FLOW_CONTINUE;
break;
case MAD_ERROR_BADLAYER: /* reserved header layer value */
break;
case MAD_ERROR_BADDATAPTR: /* bad main_data_begin pointer */
msg_Err( p_dec->p_fifo, "bad main_data_begin pointer" );
- result = MAD_FLOW_STOP;
+ result = MAD_FLOW_CONTINUE;
break;
case MAD_ERROR_BADPART3LEN: /* bad audio data length */
msg_Err( p_dec->p_fifo, "bad audio data length" );
msg_Err( p_dec->p_fifo, "unknown error occured stopping decoder" );
result = MAD_FLOW_STOP;
break;
+#endif
}
return (MAD_RECOVERABLE(p_libmad_stream->error)? result: MAD_FLOW_STOP);
- //return (MAD_FLOW_CONTINUE);
}
/*****************************************************************************
/****************************************************************************
- * Print human readable informations about an audio MPEG frame. *
+ * Print human readable informations about an audio MPEG frame.
****************************************************************************/
static void PrintFrameInfo(struct mad_header *Header)
{