[vlc-devel] [PATCH 28/39] decoder: optionally pass a vlc_video_context in decoder_UpdateVideoOutput()
Steve Lhomme
robux4 at ycbcr.xyz
Mon Oct 7 16:29:07 CEST 2019
---
include/vlc_codec.h | 4 ++--
modules/codec/avcodec/video.c | 6 +++---
modules/stream_out/mosaic_bridge.c | 4 ++--
modules/stream_out/transcode/video.c | 2 +-
src/input/decoder.c | 22 +++++++++++++++++++---
src/input/decoder_helpers.c | 6 +++---
src/misc/image.c | 3 ++-
7 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index dc1d4dda188..36d48a6204d 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -50,7 +50,7 @@ struct decoder_owner_callbacks
struct
{
vlc_decoder_device * (*get_device)( decoder_t * );
- int (*format_update)( decoder_t * );
+ int (*format_update)( decoder_t *, vlc_video_context * );
/* cf. decoder_NewPicture, can be called from any decoder thread */
picture_t* (*buffer_new)( decoder_t * );
@@ -300,7 +300,7 @@ static inline vlc_decoder_device * decoder_GetDecoderDevice( decoder_t *dec )
*
* @return 0 if the video output was set up successfully, -1 otherwise.
*/
-VLC_API int decoder_UpdateVideoOutput( decoder_t *dec );
+VLC_API int decoder_UpdateVideoOutput( decoder_t *dec, vlc_video_context *vctx_out );
/**
* Updates the video output format.
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 357a7d5d423..5e43fae2024 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -1246,7 +1246,7 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if (p_sys->p_va == NULL
&& lavc_UpdateVideoFormat(p_dec, p_context, p_context->pix_fmt,
p_context->pix_fmt, NULL) == 0
- && decoder_UpdateVideoOutput(p_dec) == 0)
+ && decoder_UpdateVideoOutput(p_dec, NULL) == 0)
p_pic = decoder_NewPicture(p_dec);
if( !p_pic )
@@ -1597,7 +1597,7 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
* update the output video format here. The MT semaphore must be held
* to protect p_dec->fmt_out. */
if (lavc_UpdateVideoFormat(dec, ctx, ctx->pix_fmt, ctx->pix_fmt, NULL) ||
- decoder_UpdateVideoOutput(dec))
+ decoder_UpdateVideoOutput(dec, NULL))
{
vlc_mutex_unlock(&sys->lock);
return -1;
@@ -1750,7 +1750,7 @@ no_reuse:
if (va == NULL)
continue; /* Unsupported codec profile or such */
- if (decoder_UpdateVideoOutput(p_dec))
+ if (decoder_UpdateVideoOutput(p_dec, NULL))
{
vlc_va_Delete(va);
p_context->hwaccel_context = NULL;
diff --git a/modules/stream_out/mosaic_bridge.c b/modules/stream_out/mosaic_bridge.c
index 0018e02c926..a7ee45edc9a 100644
--- a/modules/stream_out/mosaic_bridge.c
+++ b/modules/stream_out/mosaic_bridge.c
@@ -84,7 +84,7 @@ static void Del( sout_stream_t *, void * );
static int Send( sout_stream_t *, void *, block_t * );
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 int video_update_format_decoder( decoder_t *p_dec, vlc_video_context * );
inline static picture_t *video_new_buffer_filter( filter_t * );
static void video_update_format( video_format_t *, es_format_t * );
@@ -572,7 +572,7 @@ static int Send( sout_stream_t *p_stream, void *id, block_t *p_buffer )
return ret == VLCDEC_SUCCESS ? VLC_SUCCESS : VLC_EGENERIC;
}
-inline static int video_update_format_decoder( decoder_t *p_dec )
+inline static int video_update_format_decoder( decoder_t *p_dec, vlc_video_context *vctx )
{
struct decoder_owner *p_owner = dec_get_owner( p_dec );
video_update_format( &p_owner->video, &p_dec->fmt_out );
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 59c159ea459..04f749a9906 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -70,7 +70,7 @@ static void debug_format( sout_stream_t *p_stream, const es_format_t *fmt )
fmt->video.orientation );
}
-static int video_update_format_decoder( decoder_t *p_dec )
+static int video_update_format_decoder( decoder_t *p_dec, vlc_video_context *vctx )
{
struct decoder_owner *p_owner = dec_get_owner( p_dec );
sout_stream_id_sys_t *id = p_owner->id;
diff --git a/src/input/decoder.c b/src/input/decoder.c
index b7b4b55e751..af777e51815 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -84,6 +84,7 @@ struct decoder_owner
/* Current format in use by the output */
es_format_t fmt;
+ vlc_video_context *vctx;
/* */
atomic_bool b_fmt_description;
@@ -464,7 +465,7 @@ static void FixDisplayFormat(decoder_t *p_dec, video_format_t *fmt)
static int CreateVoutIfNeeded(struct decoder_owner *, vout_thread_t **, enum vlc_vout_order *, vlc_decoder_device **);
-static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec )
+static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *vctx )
{
struct decoder_owner *p_owner = dec_get_owner( p_dec );
@@ -473,6 +474,15 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec )
int created_vout = CreateVoutIfNeeded(p_owner, &p_vout, &vout_order, NULL);
if (created_vout == -1)
return -1; // error
+ if (created_vout == 0)
+ {
+ // video context didn't change
+ if (vctx != NULL && p_owner->vctx == vctx)
+ return 0;
+ }
+ if (p_owner->vctx)
+ vlc_video_context_Release(p_owner->vctx);
+ p_owner->vctx = vctx ? vlc_video_context_Hold(vctx) : NULL;
// configure the new vout
@@ -505,9 +515,11 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec )
.dpb_size = dpb_size + p_dec->i_extra_picture_buffers + 1,
.mouse_event = MouseEvent, .mouse_opaque = p_dec,
};
- int res = input_resource_ReconfigureVout( p_owner->p_resource, p_owner->p_dec_dev, &cfg);
+ vlc_decoder_device *dec_dev = p_owner->vctx ? vlc_video_context_HoldDevice(vctx) : NULL;
+ int res = input_resource_ReconfigureVout( p_owner->p_resource, dec_dev, &cfg);
if (res == 0)
decoder_Notify(p_owner, on_vout_started, p_vout, vout_order);
+ if (dec_dev) vlc_decoder_device_Release(dec_dev);
return res;
}
@@ -1173,8 +1185,9 @@ static void ModuleThread_QueueVideo( decoder_t *p_dec, picture_t *p_pic )
ModuleThread_UpdateStatVideo( p_owner, success != VLC_SUCCESS );
}
-static int thumbnailer_update_format( decoder_t *p_dec )
+static int thumbnailer_update_format( decoder_t *p_dec, vlc_video_context *vctx_out )
{
+ VLC_UNUSED(vctx_out);
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
return 0;
}
@@ -1994,6 +2007,9 @@ static void DeleteDecoder( decoder_t * p_dec )
if ( p_owner->p_dec_dev )
vlc_decoder_device_Release( p_owner->p_dec_dev );
+ if (p_owner->vctx)
+ vlc_video_context_Release( p_owner->vctx );
+
/* Free all packets still in the decoder fifo. */
block_FifoRelease( p_owner->p_fifo );
diff --git a/src/input/decoder_helpers.c b/src/input/decoder_helpers.c
index 0a26675a7e7..385fd111e93 100644
--- a/src/input/decoder_helpers.c
+++ b/src/input/decoder_helpers.c
@@ -80,17 +80,17 @@ int decoder_UpdateVideoFormat( decoder_t *dec )
{
vlc_decoder_device *dec_dev = decoder_GetDecoderDevice( dec );
if (dec_dev) vlc_decoder_device_Release( dec_dev );
- return decoder_UpdateVideoOutput( dec );
+ return decoder_UpdateVideoOutput( dec, NULL );
}
-int decoder_UpdateVideoOutput( decoder_t *dec )
+int decoder_UpdateVideoOutput( decoder_t *dec, vlc_video_context *vctx_out )
{
vlc_assert( dec->fmt_in.i_cat == VIDEO_ES && dec->cbs != NULL );
if ( unlikely(dec->fmt_in.i_cat != VIDEO_ES || dec->cbs == NULL ||
dec->cbs->video.format_update == NULL) )
return -1;
- return dec->cbs->video.format_update( dec );
+ return dec->cbs->video.format_update( dec, vctx_out );
}
picture_t *decoder_NewPicture( decoder_t *dec )
diff --git a/src/misc/image.c b/src/misc/image.c
index dabb2f1468c..60a4ca43c2b 100644
--- a/src/misc/image.c
+++ b/src/misc/image.c
@@ -656,8 +656,9 @@ vlc_fourcc_t image_Mime2Fourcc( const char *psz_mime )
return 0;
}
-static int video_update_format( decoder_t *p_dec )
+static int video_update_format( decoder_t *p_dec, vlc_video_context *vctx_out )
{
+ VLC_UNUSED(vctx_out);
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;
return 0;
}
--
2.17.1
More information about the vlc-devel
mailing list