- This is needed for proper seek/pause/fast forward/...
- The decoder/packetizer do not need to scale packet length anymore as the
decoder thread do it.
* @}
*/
+/**
+ * This function returns a specific input attachment (using its name).
+ *
+ * You MUST release the returned value.
+ */
VLC_EXPORT( input_attachment_t *, decoder_GetInputAttachment, ( decoder_t *, const char *psz_name ) LIBVLC_USED );
+
+/**
+ * This function gives all input attachments at once.
+ *
+ * You MUST release the returned values
+ */
VLC_EXPORT( int, decoder_GetInputAttachments, ( decoder_t *p_dec, input_attachment_t ***ppp_attachment, int *pi_attachment ) );
+
+/**
+ * This function converts a decoder timestamp into a display date comparable
+ * to mdate().
+ * You MUST use it *only* for gathering statistics about speed.
+ */
VLC_EXPORT( mtime_t, decoder_GetDisplayDate, ( decoder_t *, mtime_t ) LIBVLC_USED );
+/**
+ * This function returns the current input rate.
+ * You MUST use it *only* for gathering statistics about speed.
+ */
+VLC_EXPORT( int, decoder_GetDisplayRate, ( decoder_t * ) );
+
#endif /* _VLC_CODEC_H */
VLC_EXPORT( void, decoder_SynchroDecode, ( decoder_synchro_t * ) );
VLC_EXPORT( void, decoder_SynchroEnd, ( decoder_synchro_t *, int, bool ) );
VLC_EXPORT( mtime_t, decoder_SynchroDate, ( decoder_synchro_t * ) LIBVLC_USED );
-VLC_EXPORT( void, decoder_SynchroNewPicture, ( decoder_synchro_t *, int, int, mtime_t, mtime_t, int, bool ) );
+VLC_EXPORT( void, decoder_SynchroNewPicture, ( decoder_synchro_t *, int, int, mtime_t, mtime_t, bool ) );
#include <vlc_plugin.h>
#include <vlc_codec.h>
#include <vlc_aout.h>
-#include <vlc_input.h>
#include <vlc_block_helper.h>
#include <vlc_bits.h>
mtime_t i_pts;
int i_frame_size, i_bit_rate;
unsigned int i_rate, i_channels, i_channels_conf;
-
- int i_input_rate;
};
enum {
aout_DateSet( &p_sys->end_date, 0 );
p_sys->bytestream = block_BytestreamInit();
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
/* Set output properties */
p_dec->fmt_out.i_cat = AUDIO_ES;
return NULL;
}
- if( (*pp_block)->i_rate > 0 )
- p_sys->i_input_rate = (*pp_block)->i_rate;
-
block_BytestreamPush( &p_sys->bytestream, *pp_block );
while( 1 )
if( p_buf == NULL ) return NULL;
p_buf->start_date = aout_DateGet( &p_sys->end_date );
- p_buf->end_date = aout_DateIncrement( &p_sys->end_date,
- A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
+ p_buf->end_date = aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB );
return p_buf;
}
p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
p_block->i_length =
- aout_DateIncrement( &p_sys->end_date,
- A52_FRAME_NB * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
- p_block->i_pts;
+ aout_DateIncrement( &p_sys->end_date, A52_FRAME_NB ) - p_block->i_pts;
return p_block;
}
#include <vlc_common.h>
#include <vlc_aout.h>
#include <vlc_codec.h>
-#include <vlc_input.h>
/* ffmpeg header */
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
/* */
int i_reject_count;
-
- int i_input_rate;
};
/*****************************************************************************
p_sys->p_samples = NULL;
p_sys->i_samples = 0;
p_sys->i_reject_count = 0;
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
aout_DateSet( &p_sys->end_date, 0 );
if( p_dec->fmt_in.audio.i_rate )
}
p_buffer->start_date = aout_DateGet( &p_sys->end_date );
- p_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
- i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
+ p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes );
p_block = *pp_block;
- if( p_block->i_rate > 0 )
- p_sys->i_input_rate = p_block->i_rate;
-
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
{
block_Release( p_block );
#include <vlc_common.h>
#include <vlc_codec.h>
#include <vlc_vout.h>
-#include <vlc_input.h> /* hmmm, just for INPUT_RATE_DEFAULT */
#include <vlc_codecs.h> /* BITMAPINFOHEADER */
/* ffmpeg header */
static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * );
static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *, AVFrame * );
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
-static void ffmpeg_NextPts( decoder_t *, int i_block_rate );
+static void ffmpeg_NextPts( decoder_t * );
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{
if( !b_drawpicture && p_pic )
p_dec->pf_vout_buffer_del( p_dec, p_pic );
- ffmpeg_NextPts( p_dec, p_block->i_rate );
+ ffmpeg_NextPts( p_dec );
continue;
}
int i;
p_pic->date = p_sys->i_pts;
- ffmpeg_NextPts( p_dec, p_block->i_rate );
+ ffmpeg_NextPts( p_dec );
if( p_sys->b_first_frame )
{
}
}
-static void ffmpeg_NextPts( decoder_t *p_dec, int i_block_rate )
+static void ffmpeg_NextPts( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
{
p_sys->i_pts += INT64_C(1000000) *
(2 + p_sys->p_ff_pic->repeat_pict) *
- p_dec->fmt_in.video.i_frame_rate_base *
- i_block_rate / INPUT_RATE_DEFAULT /
+ p_dec->fmt_in.video.i_frame_rate_base /
(2 * p_dec->fmt_in.video.i_frame_rate);
}
else if( p_sys->p_context->time_base.den > 0 )
{
p_sys->i_pts += INT64_C(1000000) *
(2 + p_sys->p_ff_pic->repeat_pict) *
- p_sys->p_context->time_base.num *
- i_block_rate / INPUT_RATE_DEFAULT /
+ p_sys->p_context->time_base.num /
(2 * p_sys->p_context->time_base.den);
}
}
struct subpicture_sys_t
{
decoder_t *p_dec;
- void *p_subs_data;
- int i_subs_len;
+ void *p_subs_data;
+ int i_subs_len;
+ mtime_t i_stream_system_delta;
};
/*****************************************************************************
return NULL;
p_block = *pp_block;
- if( p_block->i_rate != 0 )
- p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
*pp_block = NULL;
if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' )
}
memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
+ p_spu->p_sys->i_stream_system_delta =
+ p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
}
static void UpdateRegions( spu_t *p_spu, subpicture_t *p_subpic,
- const video_format_t *p_fmt, mtime_t ts )
+ const video_format_t *p_fmt, mtime_t i_ts )
{
decoder_t *p_dec = p_subpic->p_sys->p_dec;
decoder_sys_t *p_sys = p_dec->p_sys;
csri_frame.pixfmt = CSRI_F_BGRA;
csri_frame.planes[0] = (unsigned char*)p_spu_region->p_picture->Y_PIXELS;
csri_frame.strides[0] = p_spu_region->p_picture->Y_PITCH;
- csri_render( p_sys->p_instance, &csri_frame, ts * 0.000001 );
+ csri_render( p_sys->p_instance, &csri_frame, (i_ts + p_subpic->p_sys->i_stream_system_delta) * 0.000001 );
}
}
#include <vlc_common.h>
#include <vlc_plugin.h>
+#include <vlc_input.h>
#include <vlc_aout.h>
#include <vlc_codec.h>
-#include <vlc_input.h>
#include <faad.h>
uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS];
bool b_sbr, b_ps;
-
- int i_input_rate;
};
static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] =
p_sys->i_buffer = p_sys->i_buffer_size = 0;
p_sys->p_buffer = NULL;
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
-
/* Faad2 can't deal with truncated data (eg. from MPEG TS) */
p_dec->b_need_packetized = true;
return NULL;
}
- if( p_block->i_rate > 0 )
- p_sys->i_input_rate = p_block->i_rate;
-
/* Remove ADTS header if we have decoder specific config */
if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 )
{
}
p_out->start_date = aout_DateGet( &p_sys->date );
- p_out->end_date = aout_DateIncrement( &p_sys->date,
- (frame.samples / frame.channels) * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
+ p_out->end_date = aout_DateIncrement( &p_sys->date, frame.samples / frame.channels );
DoReordering( (uint32_t *)p_out->p_buffer, samples,
frame.samples / frame.channels, frame.channels,
struct subpicture_sys_t
{
decoder_sys_t *p_dec_sys;
- void *p_subs_data;
- int i_subs_len;
+ void *p_subs_data;
+ int i_subs_len;
+ mtime_t i_stream_system_delta;
};
typedef struct
p_block = *pp_block;
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
{
- msg_Dbg( p_dec, "Resetting libass track after time discontinuity" );
- /* We need to reset our tracks for the time discontinuity to be
- * handled */
- vlc_mutex_lock( p_sys->p_ass->p_lock );
- if( p_sys->p_track )
- ass_free_track( p_sys->p_track );
-
- p_sys->p_track = ass_new_track( p_sys->p_ass->p_library );
- if( p_sys->p_track )
- ass_process_codec_private( p_sys->p_track,
- p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
- vlc_mutex_unlock( p_sys->p_ass->p_lock );
-
block_Release( p_block );
return NULL;
}
- if( p_block->i_rate != 0 )
- p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
*pp_block = NULL;
if( p_block->i_buffer == 0 || p_block->p_buffer[0] == '\0' )
}
memcpy( p_spu->p_sys->p_subs_data, p_block->p_buffer,
p_block->i_buffer );
+ p_spu->p_sys->i_stream_system_delta =
+ p_block->i_pts - decoder_GetDisplayDate( p_dec, p_block->i_pts );
p_spu->i_start = p_block->i_pts;
p_spu->i_stop = p_block->i_pts + p_block->i_length;
/* */
int i_changed;
- ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track, i_ts/1000, &i_changed );
+ ass_image_t *p_img = ass_render_frame( p_ass->p_renderer, p_sys->p_track,
+ (i_ts + p_subpic->p_sys->i_stream_system_delta)/1000, &i_changed );
if( !i_changed && !b_fmt_changed )
{
mtime_t i_current_pts;
mtime_t i_previous_dts;
mtime_t i_current_dts;
- int i_current_rate;
picture_t * p_picture_to_destroy;
bool b_garbage_pic;
bool b_after_sequence_header; /* is it the next frame after
if ( p_sys->b_slice_i )
{
decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
+ I_CODING_TYPE, 2, 0, 0,
p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
decoder_SynchroDecode( p_sys->p_synchro );
decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
p_sys->i_current_dts = p_block->i_dts;
}
- p_sys->i_current_rate = p_block->i_rate;
-
mpeg2_buffer( p_sys->p_mpeg2dec, p_block->p_buffer,
p_block->p_buffer + p_block->i_buffer );
/* Intra-slice refresh. Simulate a blank I picture. */
msg_Dbg( p_dec, "intra-slice refresh stream" );
decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
+ I_CODING_TYPE, 2, 0, 0,
p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
decoder_SynchroDecode( p_sys->p_synchro );
decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
p_sys->p_info->current_picture->nb_fields == 1 ? 2 :
p_sys->p_info->current_picture->nb_fields, i_pts, i_dts,
- p_sys->i_current_rate,
p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
if( !p_dec->b_pace_control && !p_sys->b_preroll &&
p_sys->b_garbage_pic );
p_sys->b_garbage_pic = 0;
- if ( p_sys->p_picture_to_destroy != p_pic )
+ if( p_sys->p_picture_to_destroy != p_pic )
{
p_pic->date = decoder_SynchroDate( p_sys->p_synchro );
}
if( p_sys->b_slice_i )
{
decoder_SynchroNewPicture( p_sys->p_synchro,
- I_CODING_TYPE, 2, 0, 0, p_sys->i_current_rate,
+ I_CODING_TYPE, 2, 0, 0,
p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
decoder_SynchroDecode( p_sys->p_synchro );
decoder_SynchroEnd( p_sys->p_synchro, I_CODING_TYPE, 0 );
#include <vlc_plugin.h>
#include <vlc_codec.h>
#include <vlc_aout.h>
-#include <vlc_input.h>
#include <vlc_block_helper.h>
unsigned int i_layer, i_bit_rate;
bool b_discontinuity;
-
- int i_input_rate;
};
enum {
aout_DateSet( &p_sys->end_date, 0 );
p_sys->bytestream = block_BytestreamInit();
p_sys->b_discontinuity = false;
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
/* Set output properties */
p_dec->fmt_out.i_cat = AUDIO_ES;
return NULL;
}
- if( (*pp_block)->i_rate > 0 )
- p_sys->i_input_rate = (*pp_block)->i_rate;
-
block_BytestreamPush( &p_sys->bytestream, *pp_block );
while( 1 )
p_buf->start_date = aout_DateGet( &p_sys->end_date );
p_buf->end_date =
- aout_DateIncrement( &p_sys->end_date,
- p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length );
p_buf->b_discontinuity = p_sys->b_discontinuity;
p_sys->b_discontinuity = false;
p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
p_block->i_length =
- aout_DateIncrement( &p_sys->end_date,
- p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
- p_block->i_pts;
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts;
return p_block;
}
/* Get the control sequence date */
date = (mtime_t)GetWBE( &p_sys->buffer[i_index] ) * 11000;
- if( p_sys->i_rate )
- date = date * p_sys->i_rate / INPUT_RATE_DEFAULT;
/* Next offset */
i_cur_seq = i_index;
/* FIXME: what the, we shouldn’t need to allocate 64k of buffer --sam. */
p_sys->i_spu = block_ChainExtract( p_spu_block, p_sys->buffer, 65536 );
p_sys->i_pts = p_spu_block->i_pts;
- p_sys->i_rate = p_spu_block->i_rate;
block_ChainRelease( p_spu_block );
/* Parse and decode */
int b_packetizer;
mtime_t i_pts;
- int i_rate;
unsigned int i_spu_size;
unsigned int i_rle_size;
unsigned int i_spu;
block_Release( p_block );
return NULL;
}
- if( p_block->i_rate != 0 )
- p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
p_spu = ParseText( p_dec, p_block );
return NULL;
p_block = *pp_block;
- if( p_block->i_rate != 0 )
- p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
p_spu = ParseText( p_dec, p_block );
#include <vlc_common.h>
#include <vlc_plugin.h>
-#include <vlc_input.h>
#include "vlc_vout.h"
#include "vlc_bits.h"
if( pp_block == NULL || *pp_block == NULL )
return NULL;
p_block = *pp_block;
- if( p_block->i_rate != 0 )
- p_block->i_length = p_block->i_length * p_block->i_rate / INPUT_RATE_DEFAULT;
*pp_block = NULL;
dbg((p_dec, "start of telx packet with header %2x\n",
audio_date_t end_date;
int i_last_block_size;
- int i_input_rate;
-
/*
** Channel reordering
*/
p_sys->i_last_block_size = 0;
p_sys->b_packetizer = false;
p_sys->i_headers = 0;
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
/* Take care of vorbis init */
vorbis_info_init( &p_sys->vi );
/* Block to Ogg packet */
oggpacket.packet = (*pp_block)->p_buffer;
oggpacket.bytes = (*pp_block)->i_buffer;
-
- if( (*pp_block)->i_rate > 0 )
- p_sys->i_input_rate = (*pp_block)->i_rate;
}
else
{
/* Date management */
p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date );
- p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date,
- i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT );
+ p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
return p_aout_buffer;
}
else
p_block->i_dts = p_block->i_pts = aout_DateGet( &p_sys->end_date );
if( p_sys->i_headers >= 3 )
- p_block->i_length = aout_DateIncrement( &p_sys->end_date,
- i_samples * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
- p_block->i_pts;
+ p_block->i_length = aout_DateIncrement( &p_sys->end_date, i_samples ) - p_block->i_pts;
else
p_block->i_length = 0;
#include <vlc_aout.h>
#include <vlc_codec.h>
#include <vlc_block.h>
-#include <vlc_sout.h>
-#include <vlc_codecs.h>
-#include <vlc_input.h>
#include <vlc_bits.h>
#include "vlc_block_helper.h"
p_sys->i_state = STATE_NOSYNC;
aout_DateSet( &p_sys->end_date, 0 );
p_sys->bytestream = block_BytestreamInit();
- p_sys->i_input_rate = INPUT_RATE_DEFAULT;
p_sys->b_latm_cfg = false;
/* Set output properties */
p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
p_block->i_length = aout_DateIncrement( &p_sys->end_date,
- p_dec->fmt_out.audio.i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) - p_block->i_pts;
+ p_dec->fmt_out.audio.i_frame_length ) - p_block->i_pts;
return p_block;
}
return NULL;
}
- if( (*pp_block)->i_rate > 0 )
- p_sys->i_input_rate = (*pp_block)->i_rate;
-
block_BytestreamPush( &p_sys->bytestream, *pp_block );
for( ;; )
p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
- p_block->i_length = aout_DateIncrement( &p_sys->end_date,
- p_sys->i_frame_length * p_sys->i_input_rate / INPUT_RATE_DEFAULT ) -
- p_block->i_pts;
+ p_block->i_length =
+ aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length ) - p_block->i_pts;
}
/*****************************************************************************
#include <vlc_sout.h>
#include <vlc_codec.h>
#include <vlc_block.h>
-#include <vlc_input.h> /* hmmm, just for INPUT_RATE_DEFAULT */
#include "vlc_bits.h"
#include "vlc_block_helper.h"
block_BytestreamFlush( &p_sys->bytestream );
p_pic->i_pts = i_pts = p_sys->bytestream.p_block->i_pts;
p_pic->i_dts = i_dts = p_sys->bytestream.p_block->i_dts;
- p_pic->i_rate = p_sys->bytestream.p_block->i_rate;
block_GetBytes( &p_sys->bytestream, p_pic->p_buffer,
p_pic->i_buffer );
p_dec->fmt_in.video.i_frame_rate_base > 0 )
{
p_sys->i_interpolated_pts += INT64_C(1000000) *
- p_dec->fmt_in.video.i_frame_rate_base *
- p_vop->i_rate / INPUT_RATE_DEFAULT /
+ p_dec->fmt_in.video.i_frame_rate_base /
p_dec->fmt_in.video.i_frame_rate;
}
else if( p_dec->p_sys->i_fps_num )
p_sys->i_interpolated_pts +=
( INT64_C(1000000) * (i_time_ref + i_time_increment -
- p_sys->i_last_time - p_sys->i_last_timeincr) *
- p_vop->i_rate / INPUT_RATE_DEFAULT /
+ p_sys->i_last_time - p_sys->i_last_timeincr) /
p_dec->p_sys->i_fps_num );
p_sys->i_last_time = i_time_ref;
block_BytestreamFlush( &p_sys->bytestream );
p_pic->i_pts = p_sys->bytestream.p_block->i_pts;
p_pic->i_dts = p_sys->bytestream.p_block->i_dts;
- p_pic->i_rate = p_sys->bytestream.p_block->i_rate;
block_GetBytes( &p_sys->bytestream, p_pic->p_buffer, p_pic->i_buffer );
return i_converted_ts + i_pts_delay;
}
+/*****************************************************************************
+ * input_clock_GetRate: Return current rate
+ *****************************************************************************/
+int input_clock_GetRate( input_clock_t *cl )
+{
+ int i_rate;
+
+ vlc_mutex_lock( &cl->lock );
+ i_rate = cl->i_rate;
+ vlc_mutex_unlock( &cl->lock );
+
+ return i_rate;
+}
/*****************************************************************************
* ClockStreamToSystem: converts a movie clock to system date
*/
mtime_t decoder_GetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
{
- VLC_UNUSED(p_dec);
- return i_ts;
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ return input_clock_GetTS( p_owner->p_clock, p_owner->p_input->i_pts_delay, i_ts );
+}
+/* decoder_GetDisplayRate:
+ */
+int decoder_GetDisplayRate( decoder_t *p_dec )
+{
+ return input_clock_GetRate( p_dec->p_owner->p_clock );
}
/**
vlc_object_release( p_cc );
return VLC_EGENERIC;
}
+ p_cc->p_owner->p_clock = p_owner->p_clock;
vlc_mutex_lock( &p_owner->lock_cc );
p_dec->p_owner->pp_cc[i_channel] = p_cc;
else if( p->i_dts > 0 )
*pi_preroll = __MIN( *pi_preroll, p->i_dts );
}
+
+static mtime_t DecoderTeletextFixTs( mtime_t i_ts, mtime_t i_ts_delay )
+{
+ mtime_t current_date = mdate();
+
+ /* FIXME I don't really like that, es_out SHOULD do it using the video pts */
+ if( !i_ts || i_ts > current_date + 10000000 || i_ts < current_date )
+ {
+ /* ETSI EN 300 472 Annex A : do not take into account the PTS
+ * for teletext streams. */
+ return current_date + 400000 + i_ts_delay;
+ }
+ return i_ts;
+}
+
+static void DecoderSoutBufferFixTs( block_t *p_block,
+ input_clock_t *p_clock, mtime_t i_ts_delay,
+ bool b_teletext )
+{
+ p_block->i_rate = input_clock_GetRate( p_clock );
+
+ if( p_block->i_dts > 0 )
+ p_block->i_dts = input_clock_GetTS( p_clock, i_ts_delay, p_block->i_dts );
+
+ if( p_block->i_pts > 0 )
+ p_block->i_pts = input_clock_GetTS( p_clock, i_ts_delay, p_block->i_pts );
+
+ if( p_block->i_length > 0 )
+ p_block->i_length = ( p_block->i_length * p_block->i_rate +
+ INPUT_RATE_DEFAULT-1 ) / INPUT_RATE_DEFAULT;
+
+ if( b_teletext )
+ p_block->i_pts = DecoderTeletextFixTs( p_block->i_pts, i_ts_delay );
+}
+static void DecoderAoutBufferFixTs( aout_buffer_t *p_buffer,
+ input_clock_t *p_clock, mtime_t i_ts_delay )
+{
+ if( p_buffer->start_date )
+ p_buffer->start_date = input_clock_GetTS( p_clock, i_ts_delay, p_buffer->start_date );
+
+ if( p_buffer->end_date )
+ p_buffer->end_date = input_clock_GetTS( p_clock, i_ts_delay, p_buffer->end_date );
+}
+static void DecoderVoutBufferFixTs( picture_t *p_picture,
+ input_clock_t *p_clock, mtime_t i_ts_delay )
+{
+ if( p_picture->date )
+ p_picture->date = input_clock_GetTS( p_clock, i_ts_delay, p_picture->date );
+}
+static void DecoderSpuBufferFixTs( subpicture_t *p_subpic,
+ input_clock_t *p_clock, mtime_t i_ts_delay,
+ bool b_teletext )
+{
+ bool b_ephemere = p_subpic->i_start == p_subpic->i_stop;
+
+ if( p_subpic->i_start )
+ p_subpic->i_start = input_clock_GetTS( p_clock, i_ts_delay, p_subpic->i_start );
+
+ if( p_subpic->i_stop )
+ p_subpic->i_stop = input_clock_GetTS( p_clock, i_ts_delay, p_subpic->i_stop );
+
+ /* Do not create ephemere picture because of rounding errors */
+ if( !b_ephemere && p_subpic->i_start == p_subpic->i_stop )
+ p_subpic->i_stop++;
+
+ if( b_teletext )
+ p_subpic->i_start = DecoderTeletextFixTs( p_subpic->i_start, i_ts_delay );
+}
+
static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
{
input_thread_t *p_input = p_dec->p_owner->p_input;
- const int i_rate = p_block->i_rate;
+ input_clock_t *p_clock = p_dec->p_owner->p_clock;
aout_buffer_t *p_aout_buf;
while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
msg_Dbg( p_dec, "End of audio preroll" );
p_dec->p_owner->i_preroll_end = -1;
}
- aout_DecPlay( p_aout, p_aout_input, p_aout_buf, i_rate );
+
+ const int i_rate = input_clock_GetRate( p_clock );
+ DecoderAoutBufferFixTs( p_aout_buf, p_clock, p_input->i_pts_delay );
+ if( i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE &&
+ i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE )
+ aout_DecPlay( p_aout, p_aout_input, p_aout_buf, i_rate );
+ else
+ aout_DecDeleteBuffer( p_aout, p_aout_input, p_aout_buf );
}
}
static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
vlc_mutex_unlock( &p_vout->picture_lock );
}
+#if 0
static void DecoderOptimizePtsDelay( decoder_t *p_dec )
{
input_thread_t *p_input = p_dec->p_owner->p_input;
vlc_mutex_unlock( &p_vout->picture_lock );
}
}
+#endif
static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
{
p_dec->p_owner->i_preroll_end = -1;
}
- if( ( !p_dec->p_owner->p_packetizer || !p_dec->p_owner->p_packetizer->pf_get_cc ) && p_dec->pf_get_cc )
+ if( p_dec->pf_get_cc &&
+ ( !p_dec->p_owner->p_packetizer || !p_dec->p_owner->p_packetizer->pf_get_cc ) )
DecoderGetCc( p_dec, p_dec );
+ DecoderVoutBufferFixTs( p_pic, p_dec->p_owner->p_clock, p_input->i_pts_delay );
+
vout_DatePicture( p_vout, p_pic, p_pic->date );
- DecoderOptimizePtsDelay( p_dec );
+ /* Re-enable it but do it right this time */
+ //DecoderOptimizePtsDelay( p_dec );
vout_DisplayPicture( p_vout, p_pic );
}
static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;
- const int i_rate = p_block ? p_block->i_rate : INPUT_RATE_DEFAULT;
+ const bool b_telx = p_dec->fmt_in.i_codec == VLC_FOURCC('t','e','l','x');
if( p_block && p_block->i_buffer <= 0 )
{
block_t *p_next = p_sout_block->p_next;
p_sout_block->p_next = NULL;
- p_sout_block->i_rate = i_rate;
+
+ DecoderSoutBufferFixTs( p_sout_block,
+ p_dec->p_owner->p_clock, p_dec->p_owner->p_input->i_pts_delay, b_telx );
sout_InputSendBuffer( p_dec->p_owner->p_sout_input,
p_sout_block );
{
block_t *p_next = p_packetized_block->p_next;
p_packetized_block->p_next = NULL;
- p_packetized_block->i_rate = i_rate;
DecoderDecodeAudio( p_dec, p_packetized_block );
{
block_t *p_next = p_packetized_block->p_next;
p_packetized_block->p_next = NULL;
- p_packetized_block->i_rate = i_rate;
DecoderDecodeVideo( p_dec, p_packetized_block );
subpicture_Delete( p_spu );
}
else
+ {
+ DecoderSpuBufferFixTs( p_spu, p_dec->p_owner->p_clock, p_input->i_pts_delay, b_telx );
spu_DisplaySubpicture( p_vout->p_spu, p_spu );
+ }
}
else
{
/* */
int i_frame_rate;
- int i_current_rate;
bool b_no_skip;
bool b_quiet;
memset( p_synchro->pi_meaningful, 0, 4 * sizeof(unsigned int) );
p_synchro->i_nb_ref = 0;
p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;
- p_synchro->current_pts = mdate() + DEFAULT_PTS_DELAY;
+ p_synchro->current_pts = 1,
p_synchro->backward_pts = 0;
p_synchro->i_current_period = p_synchro->i_backward_period = 0;
p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic =
mtime_t now, period;
mtime_t pts = 0;
bool b_decode = 0;
+ int i_current_rate;
if ( p_synchro->b_no_skip )
return 1;
+ i_current_rate = decoder_GetDisplayRate( p_synchro->p_dec );
+
now = mdate();
period = 1000000 * 1001 / p_synchro->i_frame_rate
- * p_synchro->i_current_rate / INPUT_RATE_DEFAULT;
+ * i_current_rate / INPUT_RATE_DEFAULT;
p_synchro->i_render_time = i_render_time;
case I_CODING_TYPE:
if( b_low_delay )
{
- pts = S.current_pts;
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
}
else if( S.backward_pts )
{
- pts = S.backward_pts;
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts );
}
else
{
* | +- current picture
* +- current PTS
*/
- pts = S.current_pts + period * (S.i_n_b + 2);
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ) + period * (S.i_n_b + 2);
}
if( (1 + S.i_n_p * (S.i_n_b + 1)) * period >
case P_CODING_TYPE:
if( b_low_delay )
{
- pts = S.current_pts;
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
}
else if( S.backward_pts )
{
- pts = S.backward_pts;
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts );
}
else
{
- pts = S.current_pts + period * (S.i_n_b + 1);
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts + period * (S.i_n_b + 1) );
}
if( p_synchro->i_nb_ref < 1 )
break;
case B_CODING_TYPE:
- pts = S.current_pts;
+ pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
if( p_synchro->i_nb_ref < 2 )
{
* decoder_SynchroNewPicture: Update stream structure and PTS
*****************************************************************************/
void decoder_SynchroNewPicture( decoder_synchro_t * p_synchro, int i_coding_type,
- int i_repeat_field, mtime_t next_pts,
- mtime_t next_dts, int i_current_rate,
- bool b_low_delay )
+ int i_repeat_field, mtime_t next_pts,
+ mtime_t next_dts, bool b_low_delay )
{
- mtime_t period = 1000000 * 1001 / p_synchro->i_frame_rate
- * i_current_rate / INPUT_RATE_DEFAULT;
+ mtime_t period = 1000000 * 1001 / p_synchro->i_frame_rate;
#if 0
mtime_t now = mdate();
#endif
- p_synchro->i_current_rate = i_current_rate;
switch( i_coding_type )
{
int64_t i_audio_delay;
int64_t i_spu_delay;
- /* Rate used to rescale ES ts */
+ /* Rate used for clock */
int i_rate;
/* Record */
int i;
p_sys->i_rate = i_rate;
- EsOutDiscontinuity( out, false, false );
for( i = 0; i < p_sys->i_pgrm; i++ )
input_clock_ChangeRate( p_sys->pgrm[i]->p_clock, i_rate );
*/
static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
{
- es_out_sys_t *p_sys = out->p_sys;
- input_thread_t *p_input = p_sys->p_input;
- es_out_pgrm_t *p_pgrm = es->p_pgrm;
+ es_out_sys_t *p_sys = out->p_sys;
+ input_thread_t *p_input = p_sys->p_input;
+ es_out_pgrm_t *p_pgrm = es->p_pgrm;
int64_t i_delay;
- int i_total=0;
+ int i_total = 0;
if( es->fmt.i_cat == AUDIO_ES )
i_delay = p_sys->i_audio_delay;
else
i_delay = 0;
- if( libvlc_stats (p_input) )
+ if( libvlc_stats( p_input ) )
{
vlc_mutex_lock( &p_input->p->counters.counters_lock );
stats_UpdateInteger( p_input, p_input->p->counters.p_demux_read,
es->i_preroll_end = -1;
}
- if( p_block->i_dts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) )
- {
+ if( p_block->i_dts > 0 )
p_block->i_dts += i_delay;
- }
- else if( p_block->i_dts > 0 )
- {
- p_block->i_dts =
- input_clock_GetTS( p_pgrm->p_clock, p_input->i_pts_delay, p_block->i_dts ) + i_delay;
- }
- if( p_block->i_pts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) )
- {
+
+ if( p_block->i_pts > 0 )
p_block->i_pts += i_delay;
- }
- else if( p_block->i_pts > 0 )
+
+ p_block->i_rate = 0;
+
+ if( !es->p_dec )
{
- p_block->i_pts =
- input_clock_GetTS( p_pgrm->p_clock, p_input->i_pts_delay, p_block->i_pts ) + i_delay;
+ block_Release( p_block );
+ return VLC_SUCCESS;
}
- if ( p_block->i_rate == INPUT_RATE_DEFAULT &&
- es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) )
+
+ /* Decode */
+ if( es->p_dec_record )
{
- mtime_t current_date = mdate();
- if( !p_block->i_pts
- || p_block->i_pts > current_date + 10000000
- || current_date > p_block->i_pts )
- {
- /* ETSI EN 300 472 Annex A : do not take into account the PTS
- * for teletext streams. */
- p_block->i_pts = current_date + 400000
- + p_input->i_pts_delay + i_delay;
- }
+ block_t *p_dup = block_Duplicate( p_block );
+ if( p_dup )
+ input_DecoderDecode( es->p_dec_record, p_dup );
}
+ input_DecoderDecode( es->p_dec, p_block );
- p_block->i_rate = p_sys->i_rate;
+ /* Check CC status */
+ bool pb_cc[4];
+ bool b_cc_new = false;
- /* TODO handle mute */
- if( es->p_dec &&
- ( es->fmt.i_cat != AUDIO_ES ||
- ( p_sys->i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE &&
- p_sys->i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE ) ) )
+ input_DecoderIsCcPresent( es->p_dec, pb_cc );
+ for( int i = 0; i < 4; i++ )
{
- bool pb_cc[4];
- bool b_cc_new = false;
- int i;
- if( es->p_dec_record )
- {
- block_t *p_dup = block_Duplicate( p_block );
- if( p_dup )
- input_DecoderDecode( es->p_dec_record, p_dup );
- }
- input_DecoderDecode( es->p_dec, p_block );
+ static const vlc_fourcc_t fcc[4] = {
+ VLC_FOURCC('c', 'c', '1', ' '),
+ VLC_FOURCC('c', 'c', '2', ' '),
+ VLC_FOURCC('c', 'c', '3', ' '),
+ VLC_FOURCC('c', 'c', '4', ' '),
+ };
+ es_format_t fmt;
- /* Check CC status */
- input_DecoderIsCcPresent( es->p_dec, pb_cc );
- for( i = 0; i < 4; i++ )
- {
- static const vlc_fourcc_t fcc[4] = {
- VLC_FOURCC('c', 'c', '1', ' '),
- VLC_FOURCC('c', 'c', '2', ' '),
- VLC_FOURCC('c', 'c', '3', ' '),
- VLC_FOURCC('c', 'c', '4', ' '),
- };
- es_format_t fmt;
-
- if( es->pb_cc_present[i] || !pb_cc[i] )
- continue;
- msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id );
-
- es_format_Init( &fmt, SPU_ES, fcc[i] );
- fmt.i_group = es->fmt.i_group;
- if( asprintf( &fmt.psz_description,
- _("Closed captions %u"), 1 + i ) == -1 )
- fmt.psz_description = NULL;
- es->pp_cc_es[i] = EsOutAdd( out, &fmt );
- es->pp_cc_es[i]->p_master = es;
- es_format_Clean( &fmt );
-
- /* */
- es->pb_cc_present[i] = true;
- b_cc_new = true;
- }
- if( b_cc_new )
- var_SetBool( p_sys->p_input, "intf-change", true );
- }
- else
- {
- block_Release( p_block );
+ if( es->pb_cc_present[i] || !pb_cc[i] )
+ continue;
+ msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id );
+
+ es_format_Init( &fmt, SPU_ES, fcc[i] );
+ fmt.i_group = es->fmt.i_group;
+ if( asprintf( &fmt.psz_description,
+ _("Closed captions %u"), 1 + i ) == -1 )
+ fmt.psz_description = NULL;
+ es->pp_cc_es[i] = EsOutAdd( out, &fmt );
+ es->pp_cc_es[i]->p_master = es;
+ es_format_Clean( &fmt );
+
+ /* */
+ es->pb_cc_present[i] = true;
+ b_cc_new = true;
}
+ if( b_cc_new )
+ var_SetBool( p_sys->p_input, "intf-change", true );
return VLC_SUCCESS;
}
if( !es || !es->p_dec )
return VLC_EGENERIC;
- /* XXX We should call input_clock_GetTS but PCR has been reseted
- * and it will return 0, so we won't call input_clock_GetTS on all preroll samples
- * but that's ugly(more time discontinuity), it need to be improved -- fenrir */
es->i_preroll_end = i_date;
return VLC_SUCCESS;
/**
* This functions will return a deadline used to control the reading speed.
*/
-mtime_t input_clock_GetWakeup( input_clock_t *cl );
+mtime_t input_clock_GetWakeup( input_clock_t * );
/**
* This functions allows to change the actual reading speed.
*/
-void input_clock_ChangeRate( input_clock_t *cl, int i_rate );
+void input_clock_ChangeRate( input_clock_t *, int i_rate );
/**
* This function converts a timestamp from stream clock to system clock.
*/
mtime_t input_clock_GetTS( input_clock_t *, mtime_t i_pts_delay, mtime_t );
+/**
+ * This function returns the current rate.
+ */
+int input_clock_GetRate( input_clock_t * );
+
#endif
date_Move
date_Set
decoder_GetDisplayDate
+decoder_GetDisplayRate
decoder_GetInputAttachment
decoder_GetInputAttachments
decoder_SynchroChoose