You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
5.6 KiB

#include <vlc_picture_fifo.h>
#include <vlc_filter.h>
#include <vlc_codec.h>
/*100ms is around the limit where people are noticing lipsync issues*/
#define MASTER_SYNC_MAX_DRIFT VLC_TICK_FROM_MS(100)
#define FIRSTVALID(a,b,c) ( a ? a : ( b ? b : c ) )
typedef struct sout_stream_id_sys_t sout_stream_id_sys_t;
typedef struct
{
char *psz_filters;
union
{
struct
{
char *psz_deinterlace;
config_chain_t *p_deinterlace_cfg;
} video;
};
} sout_filters_config_t;
static inline
void sout_filters_config_init( sout_filters_config_t *p_cfg )
{
memset( p_cfg, 0, sizeof(*p_cfg) );
}
static inline
void sout_filters_config_clean( sout_filters_config_t *p_cfg )
{
free( p_cfg->psz_filters );
if( p_cfg->video.psz_deinterlace )
{
free( p_cfg->video.psz_deinterlace );
config_ChainDestroy( p_cfg->video.p_deinterlace_cfg );
}
}
typedef struct
{
vlc_fourcc_t i_codec; /* (0 if not transcode) */
char *psz_name;
char *psz_lang;
config_chain_t *p_config_chain;
union
{
struct
{
unsigned int i_bitrate;
float f_scale;
unsigned int i_width, i_maxwidth;
unsigned int i_height, i_maxheight;
bool b_hurry_up;
vlc_rational_t fps;
struct
{
unsigned int i_count;
int i_priority;
uint32_t pool_size;
} threads;
} video;
struct
{
unsigned int i_bitrate;
uint32_t i_sample_rate;
uint32_t i_channels;
} audio;
struct
{
unsigned int i_width; /* render width */
unsigned int i_height;
} spu;
};
} sout_encoder_config_t;
static inline
void sout_encoder_config_init( sout_encoder_config_t *p_cfg )
{
memset( p_cfg, 0, sizeof(*p_cfg) );
}
static inline
void sout_encoder_config_clean( sout_encoder_config_t *p_cfg )
{
free( p_cfg->psz_name );
free( p_cfg->psz_lang );
config_ChainDestroy( p_cfg->p_config_chain );
}
typedef struct
{
sout_stream_id_sys_t *id_video;
spu_t *p_spu;
bool b_soverlay;
/* Audio */
sout_encoder_config_t aenc_cfg;
sout_filters_config_t afilters_cfg;
/* Video */
sout_encoder_config_t venc_cfg;
sout_filters_config_t vfilters_cfg;
/* SPU */
sout_encoder_config_t senc_cfg;
/* Sync */
bool b_master_sync;
/* i_master drift is how much audio buffer is ahead of calculated pts */
vlc_tick_t i_master_drift;
} sout_stream_sys_t;
struct aout_filters;
struct sout_stream_id_sys_t
{
bool b_transcode;
bool b_error;
/* id of the out stream */
void *downstream_id;
/* Decoder */
decoder_t *p_decoder;
struct
{
vlc_mutex_t lock;
union
{
struct {
picture_t *first;
picture_t **last;
} pic;
struct {
subpicture_t *first;
subpicture_t **last;
} spu;
struct {
block_t *first;
block_t **last;
} audio;
};
} fifo;
union
{
struct
{
filter_chain_t *p_f_chain; /**< Video filters */
filter_chain_t *p_uf_chain; /**< User-specified video filters */
filter_t *p_spu_blender;
video_format_t fmt_input_video;
video_format_t video_dec_out; /* only rw from pf_vout_format_update() */
};
struct
{
struct aout_filters *p_af_chain; /**< Audio filters */
audio_format_t fmt_input_audio;
audio_format_t audio_dec_out; /* only rw from pf_aout_format_update() */
};
};
/* Encoder */
encoder_t *p_encoder;
vlc_thread_t thread;
vlc_mutex_t lock_out;
bool b_abort;
picture_fifo_t *pp_pics;
vlc_sem_t picture_pool_has_room;
vlc_cond_t cond;
es_format_t encoder_tested_fmt_in;
/* output buffers */
block_t *p_buffers;
/* Sync */
date_t next_input_pts; /**< Incoming calculated PTS */
date_t next_output_pts; /**< output calculated PTS */
};
struct decoder_owner
{
decoder_t dec;
vlc_object_t *p_obj;
sout_stream_id_sys_t *id;
};
static inline struct decoder_owner *dec_get_owner( decoder_t *p_dec )
{
return container_of( p_dec, struct decoder_owner, dec );
}
/* SPU */
void transcode_spu_close ( sout_stream_t *, sout_stream_id_sys_t * );
int transcode_spu_process( sout_stream_t *, sout_stream_id_sys_t *,
block_t *, block_t ** );
bool transcode_spu_add ( sout_stream_t *, const es_format_t *, sout_stream_id_sys_t *);
/* AUDIO */
void transcode_audio_close ( sout_stream_id_sys_t * );
int transcode_audio_process( sout_stream_t *, sout_stream_id_sys_t *,
block_t *, block_t ** );
bool transcode_audio_add ( sout_stream_t *, const es_format_t *,
sout_stream_id_sys_t *);
/* VIDEO */
void transcode_video_close ( sout_stream_t *, sout_stream_id_sys_t * );
int transcode_video_process( sout_stream_t *, sout_stream_id_sys_t *,
block_t *, block_t ** );
bool transcode_video_add ( sout_stream_t *, const es_format_t *,
sout_stream_id_sys_t *);