vlc | branch: master | Thomas Guillem <tho...@gllm.fr> | Wed May 16 11:46:05 2018 +0200| [d49b43b6064da7b4c811cf8afd2aad708b704375] | committer: Thomas Guillem
dec: hide owner and callbacks from modules > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d49b43b6064da7b4c811cf8afd2aad708b704375 --- include/vlc_codec.h | 156 ++++++++++++---------- modules/stream_out/mosaic_bridge.c | 82 ++++++------ modules/stream_out/transcode/audio.c | 20 ++- modules/stream_out/transcode/spu.c | 17 ++- modules/stream_out/transcode/transcode.c | 7 +- modules/stream_out/transcode/transcode.h | 12 ++ modules/stream_out/transcode/video.c | 26 ++-- src/input/decoder.c | 220 +++++++++++++++++-------------- src/misc/image.c | 41 ++++-- 9 files changed, 338 insertions(+), 243 deletions(-) diff --git a/include/vlc_codec.h b/include/vlc_codec.h index 0f7f7c280b..75b9ed3ddf 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -41,10 +41,56 @@ * Decoder and encoder modules interface */ -typedef struct decoder_owner_sys_t decoder_owner_sys_t; - typedef struct decoder_cc_desc_t decoder_cc_desc_t; +struct decoder_owner_callbacks +{ + union + { + struct + { + int (*format_update)( decoder_t * ); + + /* cf. decoder_NewPicture */ + picture_t* (*buffer_new)( decoder_t * ); + /* cf.decoder_QueueVideo */ + void (*queue)( decoder_t *, picture_t * ); + /* cf.decoder_QueueCC */ + void (*queue_cc)( decoder_t *, block_t *, + const decoder_cc_desc_t * ); + + /* Display date + * cf. decoder_GetDisplayDate */ + mtime_t (*get_display_date)( decoder_t *, mtime_t ); + /* Display rate + * cf. decoder_GetDisplayRate */ + int (*get_display_rate)( decoder_t * ); + } video; + struct + { + int (*format_update)( decoder_t * ); + + /* cf.decoder_QueueAudio */ + void (*queue)( decoder_t *, block_t * ); + } audio; + struct + { + /* cf. decoder_NewSubpicture */ + subpicture_t* (*buffer_new)( decoder_t *, + const subpicture_updater_t * ); + + /* cf.decoder_QueueSub */ + void (*queue)( decoder_t *, subpicture_t *); + } spu; + }; + + /* Input attachments + * cf. decoder_GetInputAttachments */ + int (*get_attachments)( decoder_t *p_dec, + input_attachment_t ***ppp_attachment, + int *pi_attachment ); +}; + /* * BIG FAT WARNING : the code relies in the first 4 members of filter_t * and decoder_t to be the same, so if you have anything to add, do it @@ -67,6 +113,12 @@ struct decoder_t /* Tell the decoder if it is allowed to drop frames */ bool b_frame_drop_allowed; + /** + * Number of extra (ie in addition to the DPB) picture buffers + * needed for decoding. + */ + int i_extra_picture_buffers; + # define VLCDEC_SUCCESS VLC_SUCCESS # define VLCDEC_ECRITICAL VLC_EGENERIC # define VLCDEC_RELOAD (-100) @@ -138,53 +190,8 @@ struct decoder_t */ vlc_meta_t *p_description; - /* - * Owner fields - * XXX You MUST not use them directly. - */ - - /* Video output callbacks - * XXX use decoder_NewPicture */ - int (*pf_vout_format_update)( decoder_t * ); - picture_t *(*pf_vout_buffer_new)( decoder_t * ); - - /** - * Number of extra (ie in addition to the DPB) picture buffers - * needed for decoding. - */ - int i_extra_picture_buffers; - - /* Audio output callbacks */ - int (*pf_aout_format_update)( decoder_t * ); - - /* SPU output callbacks - * XXX use decoder_NewSubpicture */ - subpicture_t *(*pf_spu_buffer_new)( decoder_t *, const subpicture_updater_t * ); - - /* Input attachments - * XXX use decoder_GetInputAttachments */ - int (*pf_get_attachments)( decoder_t *p_dec, input_attachment_t ***ppp_attachment, int *pi_attachment ); - - /* Display date - * XXX use decoder_GetDisplayDate */ - mtime_t (*pf_get_display_date)( decoder_t *, mtime_t ); - - /* Display rate - * XXX use decoder_GetDisplayRate */ - int (*pf_get_display_rate)( decoder_t * ); - - /* XXX use decoder_QueueVideo or decoder_QueueVideoWithCc */ - void (*pf_queue_video)( decoder_t *, picture_t * ); - /* XXX use decoder_QueueAudio */ - void (*pf_queue_audio)( decoder_t *, block_t * ); - /* XXX use decoder_QueueCC */ - void (*pf_queue_cc)( decoder_t *, block_t *, const decoder_cc_desc_t * ); - /* XXX use decoder_QueueSub */ - void (*pf_queue_sub)( decoder_t *, subpicture_t *); - void *p_queue_ctx; - /* Private structure for the owner of the decoder */ - decoder_owner_sys_t *p_owner; + const struct decoder_owner_callbacks *cbs; }; /* struct for packetizer get_cc polling/decoder queue_cc @@ -260,9 +267,9 @@ struct encoder_t VLC_USED static inline int decoder_UpdateVideoFormat( decoder_t *dec ) { - assert( dec->fmt_in.i_cat == VIDEO_ES ); - if( dec->fmt_in.i_cat == VIDEO_ES && dec->pf_vout_format_update != NULL ) - return dec->pf_vout_format_update( dec ); + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); + if( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs->video.format_update != NULL ) + return dec->cbs->video.format_update( dec ); else return -1; } @@ -287,7 +294,8 @@ static inline int decoder_UpdateVideoFormat( decoder_t *dec ) VLC_USED static inline picture_t *decoder_NewPicture( decoder_t *dec ) { - return dec->pf_vout_buffer_new( dec ); + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); + return dec->cbs->video.buffer_new( dec ); } /** @@ -309,9 +317,10 @@ VLC_API void decoder_AbortPictures( decoder_t *dec, bool b_abort ); */ static inline void decoder_QueueVideo( decoder_t *dec, picture_t *p_pic ) { + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); assert( p_pic->p_next == NULL ); - assert( dec->pf_queue_video != NULL ); - dec->pf_queue_video( dec, p_pic ); + assert( dec->cbs->video.queue != NULL ); + dec->cbs->video.queue( dec, p_pic ); } /** @@ -324,10 +333,11 @@ static inline void decoder_QueueVideo( decoder_t *dec, picture_t *p_pic ) static inline void decoder_QueueCc( decoder_t *dec, block_t *p_cc, const decoder_cc_desc_t *p_desc ) { - if( dec->pf_queue_cc == NULL ) + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); + if( dec->cbs->video.queue_cc == NULL ) block_Release( p_cc ); else - dec->pf_queue_cc( dec, p_cc, p_desc ); + dec->cbs->video.queue_cc( dec, p_cc, p_desc ); } /** @@ -339,9 +349,10 @@ static inline void decoder_QueueCc( decoder_t *dec, block_t *p_cc, */ static inline void decoder_QueueAudio( decoder_t *dec, block_t *p_aout_buf ) { + assert( dec->fmt_in.i_cat == AUDIO_ES && dec->cbs != NULL ); assert( p_aout_buf->p_next == NULL ); - assert( dec->pf_queue_audio != NULL ); - dec->pf_queue_audio( dec, p_aout_buf ); + assert( dec->cbs->audio.queue != NULL ); + dec->cbs->audio.queue( dec, p_aout_buf ); } /** @@ -353,9 +364,10 @@ static inline void decoder_QueueAudio( decoder_t *dec, block_t *p_aout_buf ) */ static inline void decoder_QueueSub( decoder_t *dec, subpicture_t *p_spu ) { + assert( dec->fmt_in.i_cat == SPU_ES && dec->cbs != NULL ); assert( p_spu->p_next == NULL ); - assert( dec->pf_queue_sub != NULL ); - dec->pf_queue_sub( dec, p_spu ); + assert( dec->cbs->spu.queue != NULL ); + dec->cbs->spu.queue( dec, p_spu ); } /** @@ -366,9 +378,9 @@ static inline void decoder_QueueSub( decoder_t *dec, subpicture_t *p_spu ) VLC_USED static inline int decoder_UpdateAudioFormat( decoder_t *dec ) { - assert(dec->fmt_in.i_cat == AUDIO_ES); - if( dec->fmt_in.i_cat == AUDIO_ES && dec->pf_aout_format_update != NULL ) - return dec->pf_aout_format_update( dec ); + assert( dec->fmt_in.i_cat == AUDIO_ES && dec->cbs != NULL ); + if( dec->fmt_in.i_cat == AUDIO_ES && dec->cbs->audio.format_update != NULL ) + return dec->cbs->audio.format_update( dec ); else return -1; } @@ -389,7 +401,8 @@ VLC_USED static inline subpicture_t *decoder_NewSubpicture( decoder_t *dec, const subpicture_updater_t *p_dyn ) { - subpicture_t *p_subpicture = dec->pf_spu_buffer_new( dec, p_dyn ); + assert( dec->fmt_in.i_cat == SPU_ES && dec->cbs != NULL ); + subpicture_t *p_subpicture = dec->cbs->spu.buffer_new( dec, p_dyn ); if( !p_subpicture ) msg_Warn( dec, "can't get output subpicture" ); return p_subpicture; @@ -404,10 +417,11 @@ static inline int decoder_GetInputAttachments( decoder_t *dec, input_attachment_t ***ppp_attachment, int *pi_attachment ) { - if( !dec->pf_get_attachments ) + assert( dec->cbs != NULL ); + if( !dec->cbs->get_attachments ) return VLC_EGENERIC; - return dec->pf_get_attachments( dec, ppp_attachment, pi_attachment ); + return dec->cbs->get_attachments( dec, ppp_attachment, pi_attachment ); } /** @@ -418,10 +432,11 @@ static inline int decoder_GetInputAttachments( decoder_t *dec, VLC_USED static inline mtime_t decoder_GetDisplayDate( decoder_t *dec, mtime_t i_ts ) { - if( !dec->pf_get_display_date ) + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); + if( !dec->cbs->video.get_display_date ) return VLC_TS_INVALID; - return dec->pf_get_display_date( dec, i_ts ); + return dec->cbs->video.get_display_date( dec, i_ts ); } /** @@ -431,10 +446,11 @@ static inline mtime_t decoder_GetDisplayDate( decoder_t *dec, mtime_t i_ts ) VLC_USED static inline int decoder_GetDisplayRate( decoder_t *dec ) { - if( !dec->pf_get_display_rate ) + assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL ); + if( !dec->cbs->video.get_display_rate ) return 1000 /* XXX: INPUT_RATE_DEFAULT */; - return dec->pf_get_display_rate( dec ); + return dec->cbs->video.get_display_rate( dec ); } /** @} */ diff --git a/modules/stream_out/mosaic_bridge.c b/modules/stream_out/mosaic_bridge.c index 1d0c7a5944..e3d75a6a44 100644 --- a/modules/stream_out/mosaic_bridge.c +++ b/modules/stream_out/mosaic_bridge.c @@ -62,12 +62,19 @@ typedef struct filter_chain_t *p_vf2; } sout_stream_sys_t; -struct decoder_owner_sys_t +struct decoder_owner { + decoder_t dec; /* Current format in use by the output */ video_format_t video; + sout_stream_t *p_stream; }; +static inline struct decoder_owner *dec_get_owner( decoder_t *p_dec ) +{ + return container_of( p_dec, struct decoder_owner, dec ); +} + /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -77,12 +84,11 @@ static void *Add( sout_stream_t *, const es_format_t * ); static void Del( sout_stream_t *, void * ); static int Send( sout_stream_t *, void *, block_t * ); -static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ); +static void decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ); inline static int video_update_format_decoder( decoder_t *p_dec ); inline static picture_t *video_new_buffer_decoder( decoder_t * ); inline static picture_t *video_new_buffer_filter( filter_t * ); -static int video_update_format( vlc_object_t *, decoder_owner_sys_t *, - es_format_t * ); +static int video_update_format( vlc_object_t *, video_format_t *, es_format_t * ); static int HeightCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * ); @@ -282,9 +288,10 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) return NULL; /* Create decoder object */ - p_sys->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) ); - if( !p_sys->p_decoder ) + struct decoder_owner *p_owner = vlc_object_create( p_stream, sizeof( *p_owner ) ); + if( !p_owner ) return NULL; + p_sys->p_decoder = &p_owner->dec; p_sys->p_decoder->p_module = NULL; p_sys->p_decoder->fmt_in = *p_fmt; p_sys->p_decoder->b_frame_drop_allowed = true; @@ -292,18 +299,19 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) p_sys->p_decoder->fmt_out.i_extra = 0; p_sys->p_decoder->fmt_out.p_extra = 0; p_sys->p_decoder->pf_decode = NULL; - p_sys->p_decoder->pf_queue_video = decoder_queue_video; - p_sys->p_decoder->p_queue_ctx = p_stream; - p_sys->p_decoder->pf_vout_format_update = video_update_format_decoder; - p_sys->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder; - p_sys->p_decoder->p_owner = malloc( sizeof(decoder_owner_sys_t) ); - if( !p_sys->p_decoder->p_owner ) - { - vlc_object_release( p_sys->p_decoder ); - return NULL; - } - p_sys->p_decoder->p_owner->video = p_fmt->video; + static const struct decoder_owner_callbacks dec_cbs = + { + .video = { + video_update_format_decoder, + video_new_buffer_decoder, + decoder_queue_video, + }, + }; + p_sys->p_decoder->cbs = &dec_cbs; + + p_owner->video = p_fmt->video; + p_owner->p_stream = p_stream; //p_sys->p_decoder->p_cfg = p_sys->p_video_cfg; p_sys->p_decoder->p_module = @@ -312,7 +320,6 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) if( !p_sys->p_decoder->p_module ) { msg_Err( p_stream, "cannot find decoder" ); - free( p_sys->p_decoder->p_owner ); vlc_object_release( p_sys->p_decoder ); return NULL; } @@ -381,7 +388,7 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) if( psz_chain ) { filter_owner_t owner = { - .sys = p_sys->p_decoder->p_owner, + .sys = p_owner, .video = { .buffer_new = video_new_buffer_filter, }, @@ -422,16 +429,12 @@ static void Del( sout_stream_t *p_stream, void *id ) if( p_sys->p_decoder != NULL ) { - decoder_owner_sys_t *p_owner = p_sys->p_decoder->p_owner; - if( p_sys->p_decoder->p_module ) module_unneed( p_sys->p_decoder, p_sys->p_decoder->p_module ); if( p_sys->p_decoder->p_description ) vlc_meta_Delete( p_sys->p_decoder->p_description ); vlc_object_release( p_sys->p_decoder ); - - free( p_owner ); } /* Destroy user specified video filters */ @@ -480,9 +483,10 @@ static void Del( sout_stream_t *p_stream, void *id ) p_sys->b_inited = false; } -static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) +static void decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) { - sout_stream_t *p_stream = p_dec->p_queue_ctx; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_t *p_stream = p_owner->p_stream; sout_stream_sys_t *p_sys = p_stream->p_sys; picture_t *p_new_pic; const video_format_t *p_fmt_in = &p_sys->p_decoder->fmt_out.video; @@ -531,7 +535,7 @@ static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) { msg_Err( p_stream, "image conversion failed" ); picture_Release( p_pic ); - return -1; + return; } } else @@ -546,7 +550,7 @@ static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) { picture_Release( p_pic ); msg_Err( p_stream, "image allocation failed" ); - return -1; + return; } picture_Copy( p_new_pic, p_pic ); @@ -563,7 +567,6 @@ static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) p_new_pic->p_next = NULL; p_es->pp_last = &p_new_pic->p_next; vlc_global_unlock( VLC_MOSAIC_MUTEX ); - return 0; } static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer ) @@ -582,9 +585,9 @@ static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer ) inline static int video_update_format_decoder( decoder_t *p_dec ) { + struct decoder_owner *p_owner = dec_get_owner( p_dec ); return video_update_format( VLC_OBJECT( p_dec ), - (decoder_owner_sys_t *)p_dec->p_owner, - &p_dec->fmt_out ); + &p_owner->video, &p_dec->fmt_out ); } inline static picture_t *video_new_buffer_decoder( decoder_t *p_dec ) @@ -594,9 +597,9 @@ inline static picture_t *video_new_buffer_decoder( decoder_t *p_dec ) inline static picture_t *video_new_buffer_filter( filter_t *p_filter ) { + struct decoder_owner *p_owner = p_filter->owner.sys; if( video_update_format( VLC_OBJECT( p_filter ), - (decoder_owner_sys_t *)p_filter->owner.sys, - &p_filter->fmt_out ) ) { + &p_owner->video, &p_filter->fmt_out ) ) { msg_Warn( p_filter, "can't get output picture" ); return NULL; } @@ -604,15 +607,14 @@ inline static picture_t *video_new_buffer_filter( filter_t *p_filter ) } static int video_update_format( vlc_object_t *p_this, - decoder_owner_sys_t *p_sys, - es_format_t *fmt_out ) + video_format_t *video, es_format_t *fmt_out ) { VLC_UNUSED(p_this); - if( fmt_out->video.i_width != p_sys->video.i_width || - fmt_out->video.i_height != p_sys->video.i_height || - fmt_out->video.i_chroma != p_sys->video.i_chroma || - (int64_t)fmt_out->video.i_sar_num * p_sys->video.i_sar_den != - (int64_t)fmt_out->video.i_sar_den * p_sys->video.i_sar_num ) + if( fmt_out->video.i_width != video->i_width || + fmt_out->video.i_height != video->i_height || + fmt_out->video.i_chroma != video->i_chroma || + (int64_t)fmt_out->video.i_sar_num * video->i_sar_den != + (int64_t)fmt_out->video.i_sar_den * video->i_sar_num ) { vlc_ureduce( &fmt_out->video.i_sar_num, &fmt_out->video.i_sar_den, @@ -627,7 +629,7 @@ static int video_update_format( vlc_object_t *p_this, } fmt_out->video.i_chroma = fmt_out->i_codec; - p_sys->video = fmt_out->video; + *video = fmt_out->video; } /* */ diff --git a/modules/stream_out/transcode/audio.c b/modules/stream_out/transcode/audio.c index 55dc975e9e..60523d47e2 100644 --- a/modules/stream_out/transcode/audio.c +++ b/modules/stream_out/transcode/audio.c @@ -57,7 +57,8 @@ static const int pi_channels_maps[9] = static int audio_update_format( decoder_t *p_dec ) { - sout_stream_id_sys_t *id = p_dec->p_queue_ctx; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_id_sys_t *id = p_owner->id; p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec; aout_FormatPrepare( &p_dec->fmt_out.audio ); @@ -158,7 +159,8 @@ static int transcode_audio_initialize_encoder( sout_stream_id_sys_t *id, sout_st static void decoder_queue_audio( decoder_t *p_dec, block_t *p_audio ) { - sout_stream_id_sys_t *id = p_dec->p_queue_ctx; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_id_sys_t *id = p_owner->id; vlc_mutex_lock(&id->fifo.lock); *id->fifo.audio.last = p_audio; @@ -185,12 +187,18 @@ static int transcode_audio_new( sout_stream_t *p_stream, /* * Open decoder */ + dec_get_owner( id->p_decoder )->id = id; + + static const struct decoder_owner_callbacks dec_cbs = + { + .audio = { + audio_update_format, + decoder_queue_audio, + }, + }; + id->p_decoder->cbs = &dec_cbs; - /* Initialization of decoder structures */ id->p_decoder->pf_decode = NULL; - id->p_decoder->pf_queue_audio = decoder_queue_audio; - id->p_decoder->p_queue_ctx = id; - id->p_decoder->pf_aout_format_update = audio_update_format; /* id->p_decoder->p_cfg = p_sys->p_audio_cfg; */ id->p_decoder->p_module = module_need_var( id->p_decoder, "audio decoder", "codec" ); diff --git a/modules/stream_out/transcode/spu.c b/modules/stream_out/transcode/spu.c index 539c4f1828..66d3cb5fa4 100644 --- a/modules/stream_out/transcode/spu.c +++ b/modules/stream_out/transcode/spu.c @@ -47,7 +47,8 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec, static void decoder_queue_sub( decoder_t *p_dec, subpicture_t *p_spu ) { - sout_stream_id_sys_t *id = p_dec->p_queue_ctx; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_id_sys_t *id = p_owner->id; vlc_mutex_lock(&id->fifo.lock); *id->fifo.spu.last = p_spu; @@ -73,12 +74,18 @@ static int transcode_spu_new( sout_stream_t *p_stream, sout_stream_id_sys_t *id /* * Open decoder */ + dec_get_owner( id->p_decoder )->id = id; + + static const struct decoder_owner_callbacks dec_cbs = + { + .spu = { + spu_new_buffer, + decoder_queue_sub, + }, + }; + id->p_decoder->cbs = &dec_cbs; - /* Initialization of decoder structures */ id->p_decoder->pf_decode = NULL; - id->p_decoder->pf_spu_buffer_new = spu_new_buffer; - id->p_decoder->pf_queue_sub = decoder_queue_sub; - id->p_decoder->p_queue_ctx = id; /* id->p_decoder->p_cfg = p_sys->p_spu_cfg; */ id->p_decoder->p_module = diff --git a/modules/stream_out/transcode/transcode.c b/modules/stream_out/transcode/transcode.c index 1eee324a9e..ea8f7d4b5a 100644 --- a/modules/stream_out/transcode/transcode.c +++ b/modules/stream_out/transcode/transcode.c @@ -499,9 +499,12 @@ static void *Add( sout_stream_t *p_stream, const es_format_t *p_fmt ) id->p_encoder = NULL; /* Create decoder object */ - id->p_decoder = vlc_object_create( p_stream, sizeof( decoder_t ) ); - if( !id->p_decoder ) + struct decoder_owner * p_owner = vlc_object_create( p_stream, sizeof( *p_owner ) ); + if( !p_owner ) goto error; + p_owner->p_stream = p_stream; + + id->p_decoder = &p_owner->dec; id->p_decoder->p_module = NULL; es_format_Init( &id->p_decoder->fmt_out, p_fmt->i_cat, 0 ); es_format_Copy( &id->p_decoder->fmt_in, p_fmt ); diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h index e4a778d84c..071f5d20bf 100644 --- a/modules/stream_out/transcode/transcode.h +++ b/modules/stream_out/transcode/transcode.h @@ -132,6 +132,18 @@ struct sout_stream_id_sys_t }; +struct decoder_owner +{ + decoder_t dec; + sout_stream_t *p_stream; + 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 * ); diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c index 323bdfcb01..05da35115f 100644 --- a/modules/stream_out/transcode/video.c +++ b/modules/stream_out/transcode/video.c @@ -52,9 +52,10 @@ static const video_format_t* video_output_format( sout_stream_id_sys_t *id, static int video_update_format_decoder( decoder_t *p_dec ) { - sout_stream_t *stream = (sout_stream_t*) p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_id_sys_t *id = p_owner->id; + sout_stream_t *stream = p_owner->p_stream; sout_stream_sys_t *sys = stream->p_sys; - sout_stream_id_sys_t *id = p_dec->p_queue_ctx; filter_chain_t *test_chain; filter_owner_t filter_owner = { @@ -154,7 +155,8 @@ static void* EncoderThread( void *obj ) static void decoder_queue_video( decoder_t *p_dec, picture_t *p_pic ) { - sout_stream_id_sys_t *id = p_dec->p_queue_ctx; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + sout_stream_id_sys_t *id = p_owner->id; vlc_mutex_lock(&id->fifo.lock); *id->fifo.pic.last = p_pic; @@ -178,15 +180,21 @@ static int transcode_video_new( sout_stream_t *p_stream, sout_stream_id_sys_t *i sout_stream_sys_t *p_sys = p_stream->p_sys; /* Open decoder - * Initialization of decoder structures */ + dec_get_owner( id->p_decoder )->id = id; + + static const struct decoder_owner_callbacks dec_cbs = + { + .video = { + video_update_format_decoder, + video_new_buffer_decoder, + decoder_queue_video, + }, + }; + id->p_decoder->cbs = &dec_cbs; + id->p_decoder->pf_decode = NULL; - id->p_decoder->pf_queue_video = decoder_queue_video; - id->p_decoder->p_queue_ctx = id; id->p_decoder->pf_get_cc = NULL; - id->p_decoder->pf_vout_format_update = video_update_format_decoder; - id->p_decoder->pf_vout_buffer_new = video_new_buffer_decoder; - id->p_decoder->p_owner = (decoder_owner_sys_t*) p_stream; id->p_decoder->p_module = module_need_var( id->p_decoder, "video decoder", "codec" ); diff --git a/src/input/decoder.c b/src/input/decoder.c index ee559043e9..32b91b63e8 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -63,8 +63,9 @@ enum reload RELOAD_DECODER_AOUT /* Stop the aout and reload the decoder module */ }; -struct decoder_owner_sys_t +struct decoder_owner { + decoder_t dec; input_thread_t *p_input; input_resource_t*p_resource; input_clock_t *p_clock; @@ -79,7 +80,7 @@ struct decoder_owner_sys_t vlc_thread_t thread; - void (*pf_update_stat)( decoder_owner_sys_t *, unsigned decoded, unsigned lost ); + void (*pf_update_stat)( struct decoder_owner *, unsigned decoded, unsigned lost ); /* Some decoders require already packetized data (ie. not truncated) */ decoder_t *p_packetizer; @@ -153,6 +154,11 @@ struct decoder_owner_sys_t #define VLC_TS_OLDEST (VLC_TS_INVALID + 1) +static inline struct decoder_owner *dec_get_owner( decoder_t *p_dec ) +{ + return container_of( p_dec, struct decoder_owner, dec ); +} + /** * Load a decoder module */ @@ -218,20 +224,20 @@ static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer, const es_format_t *restrict p_fmt, enum reload reload ) { /* Copy p_fmt since it can be destroyed by UnloadDecoder */ + struct decoder_owner *p_owner = dec_get_owner( p_dec ); es_format_t fmt_in; if( es_format_Copy( &fmt_in, p_fmt ) != VLC_SUCCESS ) { - p_dec->p_owner->error = true; + p_owner->error = true; return VLC_EGENERIC; } /* Restart the decoder module */ UnloadDecoder( p_dec ); - p_dec->p_owner->error = false; + p_owner->error = false; if( reload == RELOAD_DECODER_AOUT ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; assert( p_owner->fmt.i_cat == AUDIO_ES ); audio_output_t *p_aout = p_owner->p_aout; @@ -247,7 +253,7 @@ static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer, if( LoadDecoder( p_dec, b_packetizer, &fmt_in ) ) { - p_dec->p_owner->error = true; + p_owner->error = true; es_format_Clean( &fmt_in ); return VLC_EGENERIC; } @@ -257,7 +263,7 @@ static int ReloadDecoder( decoder_t *p_dec, bool b_packetizer, static void DecoderUpdateFormatLocked( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_assert_locked( &p_owner->lock ); @@ -284,7 +290,7 @@ static vout_thread_t *aout_request_vout( void *p_private, const video_format_t *p_fmt, bool b_recyle ) { decoder_t *p_dec = p_private; - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); input_thread_t *p_input = p_owner->p_input; p_vout = input_resource_RequestVout( p_owner->p_resource, p_vout, p_fmt, 1, @@ -311,7 +317,7 @@ static bool aout_replaygain_changed( const audio_replay_gain_t *a, static int aout_update_format( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if( p_owner->p_aout && ( !AOUT_FMTS_IDENTICAL(&p_dec->fmt_out.audio, &p_owner->fmt.audio) || @@ -407,7 +413,7 @@ static int aout_update_format( decoder_t *p_dec ) static int vout_update_format( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if( p_owner->p_vout == NULL || p_dec->fmt_out.video.i_width != p_owner->fmt.video.i_width @@ -553,7 +559,7 @@ static int vout_update_format( decoder_t *p_dec ) static picture_t *vout_new_buffer( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( p_owner->p_vout ); return vout_GetPicture( p_owner->p_vout ); @@ -562,7 +568,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec ) static subpicture_t *spu_new_buffer( decoder_t *p_dec, const subpicture_updater_t *p_updater ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vout_thread_t *p_vout = NULL; subpicture_t *p_subpic; int i_attempts = 30; @@ -609,7 +615,8 @@ static int DecoderGetInputAttachments( decoder_t *p_dec, input_attachment_t ***ppp_attachment, int *pi_attachment ) { - input_thread_t *p_input = p_dec->p_owner->p_input; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + input_thread_t *p_input = p_owner->p_input; if( unlikely(p_input == NULL) ) return VLC_ENOOBJ; @@ -619,7 +626,7 @@ static int DecoderGetInputAttachments( decoder_t *p_dec, static mtime_t DecoderGetDisplayDate( decoder_t *p_dec, mtime_t i_ts ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); if( p_owner->b_waiting || p_owner->paused ) @@ -639,7 +646,7 @@ static mtime_t DecoderGetDisplayDate( decoder_t *p_dec, mtime_t i_ts ) static int DecoderGetDisplayRate( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if( !p_owner->p_clock ) return INPUT_RATE_DEFAULT; @@ -667,7 +674,7 @@ block_t *decoder_NewAudioBuffer( decoder_t *dec, int samples ) static void RequestReload( decoder_t * p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); /* Don't override reload if it's RELOAD_DECODER_AOUT */ int expected = RELOAD_NO_REQUEST; atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER ); @@ -675,7 +682,7 @@ static void RequestReload( decoder_t * p_dec ) void decoder_AbortPictures( decoder_t *p_dec, bool b_abort ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); if( p_owner->p_vout != NULL ) @@ -685,7 +692,7 @@ void decoder_AbortPictures( decoder_t *p_dec, bool b_abort ) static void DecoderWaitUnblock( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_assert_locked( &p_owner->lock ); @@ -701,7 +708,7 @@ static void DecoderWaitUnblock( decoder_t *p_dec ) * Returns VLC_SUCCESS if wait was not interrupted, and VLC_EGENERIC otherwise */ static int DecoderTimedWait( decoder_t *p_dec, mtime_t deadline ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if (deadline - mdate() <= 0) return VLC_SUCCESS; @@ -732,7 +739,7 @@ static inline void DecoderUpdatePreroll( mtime_t *pi_preroll, const block_t *p ) static void DecoderFixTs( decoder_t *p_dec, mtime_t *pi_ts0, mtime_t *pi_ts1, mtime_t *pi_duration, int *pi_rate, mtime_t i_ts_bound ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); input_clock_t *p_clock = p_owner->p_clock; vlc_assert_locked( &p_owner->lock ); @@ -782,7 +789,7 @@ static void DecoderFixTs( decoder_t *p_dec, mtime_t *pi_ts0, mtime_t *pi_ts1, #ifdef ENABLE_SOUT static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( p_owner->p_clock ); assert( !p_sout_block->p_next ); @@ -809,7 +816,7 @@ static int DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block ) */ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); block_t *p_sout_block; block_t **pp_block = p_block ? &p_block : NULL; @@ -879,7 +886,7 @@ static void DecoderProcessSout( decoder_t *p_dec, block_t *p_block ) static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc, const decoder_cc_desc_t *p_desc ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); @@ -893,16 +900,17 @@ static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc, for( int i=0; i_bitmap > 0; i_bitmap >>= 1, i++ ) { decoder_t *p_ccdec = p_owner->cc.pp_decoder[i]; + struct decoder_owner *p_ccowner = dec_get_owner( p_ccdec ); if( !p_ccdec ) continue; if( i_bitmap > 1 ) { - block_FifoPut( p_ccdec->p_owner->p_fifo, block_Duplicate(p_cc) ); + block_FifoPut( p_ccowner->p_fifo, block_Duplicate(p_cc) ); } else { - block_FifoPut( p_ccdec->p_owner->p_fifo, p_cc ); + block_FifoPut( p_ccowner->p_fifo, p_cc ); p_cc = NULL; /* was last dec */ } } @@ -915,7 +923,7 @@ static void DecoderPlayCc( decoder_t *p_dec, block_t *p_cc, static void PacketizerGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); block_t *p_cc; decoder_cc_desc_t desc; @@ -934,7 +942,7 @@ static void PacketizerGetCc( decoder_t *p_dec, decoder_t *p_dec_cc ) static void DecoderQueueCc( decoder_t *p_videodec, block_t *p_cc, const decoder_cc_desc_t *p_desc ) { - decoder_owner_sys_t *p_owner = p_videodec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_videodec ); if( unlikely( p_cc != NULL ) ) { @@ -949,7 +957,7 @@ static void DecoderQueueCc( decoder_t *p_videodec, block_t *p_cc, static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture, unsigned *restrict pi_lost_sum ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vout_thread_t *p_vout = p_owner->p_vout; bool prerolled; @@ -1043,7 +1051,7 @@ discard: picture_Release( p_picture ); } -static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner, +static void DecoderUpdateStatVideo( struct decoder_owner *p_owner, unsigned decoded, unsigned lost ) { input_thread_t *p_input = p_owner->p_input; @@ -1078,7 +1086,7 @@ static void DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic ) { assert( p_pic ); unsigned i_lost = 0; - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); DecoderPlayVideo( p_dec, p_pic, &i_lost ); @@ -1088,7 +1096,7 @@ static void DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic ) static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio, unsigned *restrict pi_lost_sum ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); bool prerolled; assert( p_audio != NULL ); @@ -1168,7 +1176,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio, return; } -static void DecoderUpdateStatAudio( decoder_owner_sys_t *p_owner, +static void DecoderUpdateStatAudio( struct decoder_owner *p_owner, unsigned decoded, unsigned lost ) { input_thread_t *p_input = p_owner->p_input; @@ -1202,7 +1210,7 @@ static void DecoderUpdateStatAudio( decoder_owner_sys_t *p_owner, static void DecoderQueueAudio( decoder_t *p_dec, block_t *p_aout_buf ) { unsigned lost = 0; - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); DecoderPlayAudio( p_dec, p_aout_buf, &lost ); @@ -1211,7 +1219,7 @@ static void DecoderQueueAudio( decoder_t *p_dec, block_t *p_aout_buf ) static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vout_thread_t *p_vout = p_owner->p_spu_vout; /* */ @@ -1246,7 +1254,7 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic ) vout_PutSubpicture( p_vout, p_subpic ); } -static void DecoderUpdateStatSpu( decoder_owner_sys_t *p_owner, +static void DecoderUpdateStatSpu( struct decoder_owner *p_owner, unsigned decoded, unsigned lost ) { (void) p_owner; (void) decoded; (void) lost; @@ -1255,7 +1263,7 @@ static void DecoderUpdateStatSpu( decoder_owner_sys_t *p_owner, static void DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu ) { assert( p_spu ); - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource ); if( p_vout && p_owner->p_spu_vout == p_vout ) @@ -1286,7 +1294,7 @@ static void DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu ) static void DecoderProcess( decoder_t *p_dec, block_t *p_block ); static void DecoderDecode( decoder_t *p_dec, block_t *p_block ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); int ret = p_dec->pf_decode( p_dec, p_block ); switch( ret ) @@ -1322,7 +1330,7 @@ static void DecoderDecode( decoder_t *p_dec, block_t *p_block ) */ static void DecoderProcess( decoder_t *p_dec, block_t *p_block ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if( p_owner->error ) goto error; @@ -1421,7 +1429,7 @@ error: static void DecoderProcessFlush( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); decoder_t *p_packetizer = p_owner->p_packetizer; if( p_owner->error ) @@ -1487,7 +1495,7 @@ static void DecoderProcessFlush( decoder_t *p_dec ) static void *DecoderThread( void *p_data ) { decoder_t *p_dec = (decoder_t *)p_data; - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); float rate = 1.f; bool paused = false; @@ -1608,6 +1616,35 @@ static void *DecoderThread( void *p_data ) vlc_assert_unreachable(); } +static const struct decoder_owner_callbacks dec_video_cbs = +{ + .video = { + vout_update_format, + vout_new_buffer, + DecoderQueueVideo, + DecoderQueueCc, + DecoderGetDisplayDate, + DecoderGetDisplayRate + }, + DecoderGetInputAttachments, +}; +static const struct decoder_owner_callbacks dec_audio_cbs = +{ + .audio = { + aout_update_format, + DecoderQueueAudio, + }, + DecoderGetInputAttachments, +}; +static const struct decoder_owner_callbacks dec_spu_cbs = +{ + .spu = { + spu_new_buffer, + DecoderQueueSpu + }, + DecoderGetInputAttachments, +}; + /** * Create a decoder object * @@ -1623,19 +1660,13 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, sout_instance_t *p_sout ) { decoder_t *p_dec; - decoder_owner_sys_t *p_owner; + struct decoder_owner *p_owner; - p_dec = vlc_custom_create( p_parent, sizeof( *p_dec ), "decoder" ); - if( p_dec == NULL ) + p_owner = vlc_custom_create( p_parent, sizeof( *p_owner ), "decoder" ); + if( p_owner == NULL ) return NULL; + p_dec = &p_owner->dec; - /* Allocate our private structure for the decoder */ - p_dec->p_owner = p_owner = malloc( sizeof( decoder_owner_sys_t ) ); - if( unlikely(p_owner == NULL) ) - { - vlc_object_release( p_dec ); - return NULL; - } p_owner->i_preroll_end = (mtime_t)INT64_MIN; p_owner->i_last_rate = INPUT_RATE_DEFAULT; p_owner->p_input = p_input; @@ -1675,7 +1706,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, p_owner->p_fifo = block_FifoNew(); if( unlikely(p_owner->p_fifo == NULL) ) { - free( p_owner ); vlc_object_release( p_dec ); return NULL; } @@ -1686,16 +1716,6 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, vlc_cond_init( &p_owner->wait_fifo ); vlc_cond_init( &p_owner->wait_timed ); - /* Set buffers allocation callbacks for the decoders */ - p_dec->pf_aout_format_update = aout_update_format; - p_dec->pf_vout_format_update = vout_update_format; - p_dec->pf_vout_buffer_new = vout_new_buffer; - p_dec->pf_spu_buffer_new = spu_new_buffer; - /* */ - p_dec->pf_get_attachments = DecoderGetInputAttachments; - p_dec->pf_get_display_date = DecoderGetDisplayDate; - p_dec->pf_get_display_rate = DecoderGetDisplayRate; - /* Load a packetizer module if the input is not already packetized */ if( p_sout == NULL && !fmt->b_packetized ) { @@ -1716,30 +1736,31 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, } } - /* Find a suitable decoder/packetizer module */ - if( LoadDecoder( p_dec, p_sout != NULL, fmt ) ) - return p_dec; - - switch( p_dec->fmt_out.i_cat ) + switch( fmt->i_cat ) { case VIDEO_ES: - p_dec->pf_queue_video = DecoderQueueVideo; - p_dec->pf_queue_cc = DecoderQueueCc; + p_dec->cbs = &dec_video_cbs; p_owner->pf_update_stat = DecoderUpdateStatVideo; break; case AUDIO_ES: - p_dec->pf_queue_audio = DecoderQueueAudio; + p_dec->cbs = &dec_audio_cbs; p_owner->pf_update_stat = DecoderUpdateStatAudio; break; case SPU_ES: - p_dec->pf_queue_sub = DecoderQueueSpu; + p_dec->cbs = &dec_spu_cbs; p_owner->pf_update_stat = DecoderUpdateStatSpu; break; default: msg_Err( p_dec, "unknown ES format" ); - UnloadDecoder( p_dec ); return p_dec; } + + /* Find a suitable decoder/packetizer module */ + if( LoadDecoder( p_dec, p_sout != NULL, fmt ) ) + return p_dec; + + assert( p_dec->fmt_in.i_cat == p_dec->fmt_out.i_cat && fmt->i_cat == p_dec->fmt_in.i_cat); + /* Copy ourself the input replay gain */ if( fmt->i_cat == AUDIO_ES ) { @@ -1777,7 +1798,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, */ static void DeleteDecoder( decoder_t * p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); msg_Dbg( p_dec, "killing decoder fourcc `%4.4s'", (char*)&p_dec->fmt_in.i_codec ); @@ -1845,8 +1866,6 @@ static void DeleteDecoder( decoder_t * p_dec ) vlc_mutex_destroy( &p_owner->lock ); vlc_object_release( p_dec ); - - free( p_owner ); } /* */ @@ -1895,7 +1914,8 @@ static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input, return NULL; } - p_dec->p_owner->p_clock = p_clock; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + p_owner->p_clock = p_clock; assert( p_dec->fmt_out.i_cat != UNKNOWN_ES ); if( p_dec->fmt_out.i_cat == AUDIO_ES ) @@ -1908,7 +1928,6 @@ static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input, if( p_sout && fmt->b_packetized && (fmt->i_cat != VIDEO_ES && fmt->i_cat != AUDIO_ES) ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; p_owner->p_sout_input = sout_InputNew( p_owner->p_sout, fmt ); if( p_owner->p_sout_input == NULL ) { @@ -1920,7 +1939,7 @@ static decoder_t *decoder_New( vlc_object_t *p_parent, input_thread_t *p_input, #endif /* Spawn the decoder thread */ - if( vlc_clone( &p_dec->p_owner->thread, DecoderThread, p_dec, i_priority ) ) + if( vlc_clone( &p_owner->thread, DecoderThread, p_dec, i_priority ) ) { msg_Err( p_dec, "cannot spawn decoder thread" ); DeleteDecoder( p_dec ); @@ -1965,7 +1984,7 @@ decoder_t *input_DecoderCreate( vlc_object_t *p_parent, const es_format_t *fmt, */ void input_DecoderDelete( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_cancel( p_owner->thread ); @@ -1994,7 +2013,7 @@ void input_DecoderDelete( decoder_t *p_dec ) vlc_join( p_owner->thread, NULL ); /* */ - if( p_dec->p_owner->cc.b_supported ) + if( p_owner->cc.b_supported ) { for( int i = 0; i < MAX_CC_DECODERS; i++ ) input_DecoderSetCcState( p_dec, VLC_CODEC_CEA608, i, false ); @@ -2013,7 +2032,7 @@ void input_DecoderDelete( decoder_t *p_dec ) */ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_fifo_Lock( p_owner->p_fifo ); if( !b_do_pace ) @@ -2044,12 +2063,12 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace ) bool input_DecoderIsEmpty( decoder_t * p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( !p_owner->b_waiting ); vlc_fifo_Lock( p_owner->p_fifo ); - if( !vlc_fifo_IsEmpty( p_dec->p_owner->p_fifo ) || p_owner->b_draining ) + if( !vlc_fifo_IsEmpty( p_owner->p_fifo ) || p_owner->b_draining ) { vlc_fifo_Unlock( p_owner->p_fifo ); return false; @@ -2085,7 +2104,7 @@ bool input_DecoderIsEmpty( decoder_t * p_dec ) */ void input_DecoderDrain( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_fifo_Lock( p_owner->p_fifo ); p_owner->b_draining = true; @@ -2099,7 +2118,7 @@ void input_DecoderDrain( decoder_t *p_dec ) */ void input_DecoderFlush( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_fifo_Lock( p_owner->p_fifo ); @@ -2127,7 +2146,7 @@ void input_DecoderFlush( decoder_t *p_dec ) void input_DecoderGetCcDesc( decoder_t *p_dec, decoder_cc_desc_t *p_desc ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); *p_desc = p_owner->cc.desc; @@ -2137,7 +2156,7 @@ void input_DecoderGetCcDesc( decoder_t *p_dec, decoder_cc_desc_t *p_desc ) static bool input_DecoderHasCCChanFlag( decoder_t *p_dec, vlc_fourcc_t codec, int i_channel ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); int i_max_channels; uint64_t i_bitmap; @@ -2160,7 +2179,7 @@ static bool input_DecoderHasCCChanFlag( decoder_t *p_dec, int input_DecoderSetCcState( decoder_t *p_dec, vlc_fourcc_t codec, int i_channel, bool b_decode ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); //msg_Warn( p_dec, "input_DecoderSetCcState: %d @%x", b_decode, i_channel ); @@ -2176,7 +2195,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, vlc_fourcc_t codec, fmt.subs.cc.i_channel = i_channel; fmt.subs.cc.i_reorder_depth = p_owner->cc.desc.i_reorder_depth; p_cc = input_DecoderNew( p_owner->p_input, &fmt, - p_dec->p_owner->p_clock, p_owner->p_sout ); + p_owner->p_clock, p_owner->p_sout ); if( !p_cc ) { msg_Err( p_dec, "could not create decoder" ); @@ -2191,7 +2210,8 @@ int input_DecoderSetCcState( decoder_t *p_dec, vlc_fourcc_t codec, input_DecoderDelete(p_cc); return VLC_EGENERIC; } - p_cc->p_owner->p_clock = p_owner->p_clock; + struct decoder_owner *p_ccowner = dec_get_owner( p_cc ); + p_ccowner->p_clock = p_owner->p_clock; vlc_mutex_lock( &p_owner->lock ); p_owner->cc.pp_decoder[i_channel] = p_cc; @@ -2215,7 +2235,7 @@ int input_DecoderSetCcState( decoder_t *p_dec, vlc_fourcc_t codec, int input_DecoderGetCcState( decoder_t *p_dec, vlc_fourcc_t codec, int i_channel, bool *pb_decode ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); if( !input_DecoderHasCCChanFlag( p_dec, codec, i_channel ) ) return VLC_EGENERIC; @@ -2228,7 +2248,7 @@ int input_DecoderGetCcState( decoder_t *p_dec, vlc_fourcc_t codec, void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); /* Normally, p_owner->b_paused != b_paused here. But if a track is added * while the input is paused (e.g. add sub file), then b_paused is @@ -2243,7 +2263,7 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ) void input_DecoderChangeRate( decoder_t *dec, float rate ) { - decoder_owner_sys_t *owner = dec->p_owner; + struct decoder_owner *owner = dec_get_owner( dec ); vlc_fifo_Lock( owner->p_fifo ); owner->rate = rate; @@ -2253,7 +2273,7 @@ void input_DecoderChangeRate( decoder_t *dec, float rate ) void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); p_owner->i_ts_delay = i_delay; @@ -2262,7 +2282,7 @@ void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay ) void input_DecoderStartWait( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( !p_owner->b_waiting ); @@ -2276,7 +2296,7 @@ void input_DecoderStartWait( decoder_t *p_dec ) void input_DecoderStopWait( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( p_owner->b_waiting ); @@ -2288,7 +2308,7 @@ void input_DecoderStopWait( decoder_t *p_dec ) void input_DecoderWait( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( p_owner->b_waiting ); @@ -2314,7 +2334,7 @@ void input_DecoderWait( decoder_t *p_dec ) void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); assert( p_owner->paused ); *pi_duration = 0; @@ -2335,7 +2355,7 @@ void input_DecoderFrameNext( decoder_t *p_dec, mtime_t *pi_duration ) bool input_DecoderHasFormatChanged( decoder_t *p_dec, es_format_t *p_fmt, vlc_meta_t **pp_meta ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); bool b_changed; vlc_mutex_lock( &p_owner->lock ); @@ -2363,7 +2383,7 @@ bool input_DecoderHasFormatChanged( decoder_t *p_dec, es_format_t *p_fmt, vlc_me size_t input_DecoderGetFifoSize( decoder_t *p_dec ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); return block_FifoSize( p_owner->p_fifo ); } @@ -2371,7 +2391,7 @@ size_t input_DecoderGetFifoSize( decoder_t *p_dec ) void input_DecoderGetObjects( decoder_t *p_dec, vout_thread_t **pp_vout, audio_output_t **pp_aout ) { - decoder_owner_sys_t *p_owner = p_dec->p_owner; + struct decoder_owner *p_owner = dec_get_owner( p_dec ); vlc_mutex_lock( &p_owner->lock ); if( pp_vout ) diff --git a/src/misc/image.c b/src/misc/image.c index 721a1e6118..2d55ec51d1 100644 --- a/src/misc/image.c +++ b/src/misc/image.c @@ -49,6 +49,17 @@ #include <libvlc.h> #include <vlc_modules.h> +struct decoder_owner +{ + decoder_t dec; + image_handler_t *p_image; +}; + +static inline struct decoder_owner *dec_get_owner( decoder_t *p_dec ) +{ + return container_of( p_dec, struct decoder_owner, dec ); +} + static picture_t *ImageRead( image_handler_t *, block_t *, const video_format_t *, video_format_t * ); static picture_t *ImageReadUrl( image_handler_t *, const char *, @@ -61,7 +72,7 @@ static int ImageWriteUrl( image_handler_t *, picture_t *, static picture_t *ImageConvert( image_handler_t *, picture_t *, const video_format_t *, video_format_t * ); -static decoder_t *CreateDecoder( vlc_object_t *, const video_format_t * ); +static decoder_t *CreateDecoder( image_handler_t *, const video_format_t * ); static void DeleteDecoder( decoder_t * ); static encoder_t *CreateEncoder( vlc_object_t *, const video_format_t *, const video_format_t * ); @@ -123,8 +134,8 @@ void image_HandlerDelete( image_handler_t *p_image ) static void ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic ) { - image_handler_t *p_image = p_dec->p_queue_ctx; - picture_fifo_Push( p_image->outfifo, p_pic ); + struct decoder_owner *p_owner = dec_get_owner( p_dec ); + picture_fifo_Push( p_owner->p_image->outfifo, p_pic ); } static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block, @@ -144,7 +155,7 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block, /* Start a decoder */ if( !p_image->p_dec ) { - p_image->p_dec = CreateDecoder( p_image->p_parent, p_fmt_in ); + p_image->p_dec = CreateDecoder( p_image, p_fmt_in ); if( !p_image->p_dec ) { block_Release(p_block); @@ -157,8 +168,6 @@ static picture_t *ImageRead( image_handler_t *p_image, block_t *p_block, block_Release(p_block); return NULL; } - p_image->p_dec->pf_queue_video = ImageQueueVideo; - p_image->p_dec->p_queue_ctx = p_image; } p_block->i_pts = p_block->i_dts = mdate(); @@ -661,21 +670,31 @@ static picture_t *video_new_buffer( decoder_t *p_dec ) return picture_NewFromFormat( &p_dec->fmt_out.video ); } -static decoder_t *CreateDecoder( vlc_object_t *p_this, const video_format_t *fmt ) +static decoder_t *CreateDecoder( image_handler_t *p_image, const video_format_t *fmt ) { decoder_t *p_dec; + struct decoder_owner *p_owner; - p_dec = vlc_custom_create( p_this, sizeof( *p_dec ), "image decoder" ); - if( p_dec == NULL ) + p_owner = vlc_custom_create( p_image->p_parent, sizeof( *p_owner ), "image decoder" ); + if( p_owner == NULL ) return NULL; + p_dec = &p_owner->dec; + p_owner->p_image = p_image; p_dec->p_module = NULL; es_format_InitFromVideo( &p_dec->fmt_in, fmt ); es_format_Init( &p_dec->fmt_out, VIDEO_ES, 0 ); p_dec->b_frame_drop_allowed = false; - p_dec->pf_vout_format_update = video_update_format; - p_dec->pf_vout_buffer_new = video_new_buffer; + static const struct decoder_owner_callbacks dec_cbs = + { + .video = { + video_update_format, + video_new_buffer, + ImageQueueVideo, + }, + }; + p_dec->cbs = &dec_cbs; /* Find a suitable decoder module */ p_dec->p_module = module_need_var( p_dec, "video decoder", "codec" ); _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits