[vlc-devel] [PATCH 6/9] decoder: use a local decoder picture pool rather than using the display one
Steve Lhomme
robux4 at ycbcr.xyz
Fri Oct 18 17:11:11 CEST 2019
For now the software pool is created even in hardware decoding. It doesn't use
much memory as there's no planes allocated.
---
src/input/decoder.c | 81 +++++++++++++++++++++++----------
src/video_output/video_output.c | 2 +-
2 files changed, 59 insertions(+), 24 deletions(-)
diff --git a/src/input/decoder.c b/src/input/decoder.c
index f979fca5e1f..46cf7658b8a 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -42,6 +42,7 @@
#include <vlc_dialog.h>
#include <vlc_modules.h>
#include <vlc_decoder.h>
+#include <vlc_picture_pool.h>
#include "audio_output/aout_internal.h"
#include "stream_output/stream_output.h"
@@ -100,6 +101,9 @@ struct decoder_owner
vlc_cond_t wait_acknowledge;
vlc_cond_t wait_fifo; /* TODO: merge with wait_acknowledge */
+ /* pool to use when the decoder doesn't use its own */
+ struct picture_pool_t *out_pool;
+
/*
* 3 threads can read/write these output variables, the DecoderThread, the
* input thread, and the ModuleThread. The ModuleThread is either the
@@ -485,31 +489,39 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
video_format_t fmt;
FixDisplayFormat( p_dec, &fmt );
- unsigned dpb_size;
- switch( p_dec->fmt_in.i_codec )
- {
- case VLC_CODEC_HEVC:
- case VLC_CODEC_H264:
- case VLC_CODEC_DIRAC: /* FIXME valid ? */
- dpb_size = 18;
- break;
- case VLC_CODEC_AV1:
- dpb_size = 10;
- break;
- case VLC_CODEC_VP5:
- case VLC_CODEC_VP6:
- case VLC_CODEC_VP6F:
- case VLC_CODEC_VP8:
- dpb_size = 3;
- break;
- default:
- dpb_size = 2;
- break;
+ if ( p_owner->out_pool == NULL )
+ {
+ unsigned dpb_size;
+ switch( p_dec->fmt_in.i_codec )
+ {
+ case VLC_CODEC_HEVC:
+ case VLC_CODEC_H264:
+ case VLC_CODEC_DIRAC: /* FIXME valid ? */
+ dpb_size = 18;
+ break;
+ case VLC_CODEC_AV1:
+ dpb_size = 10;
+ break;
+ case VLC_CODEC_VP5:
+ case VLC_CODEC_VP6:
+ case VLC_CODEC_VP6F:
+ case VLC_CODEC_VP8:
+ dpb_size = 3;
+ break;
+ default:
+ dpb_size = 2;
+ break;
+ }
+
+ p_owner->out_pool = picture_pool_NewFromFormat( &fmt,
+ dpb_size + p_dec->i_extra_picture_buffers + 1 );
+ if (p_owner->out_pool == NULL)
+ return -1;
}
int res;
if (p_owner->vout_thread_started)
{
- res = vout_ChangeSource(p_vout, &fmt, dpb_size + p_dec->i_extra_picture_buffers + 1);
+ res = vout_ChangeSource(p_vout, &fmt, 0);
if (res == 0)
// the display/thread is started and can handle the new source format
return 0;
@@ -517,7 +529,7 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
vout_configuration_t cfg = {
.vout = p_vout, .clock = p_owner->p_clock, .fmt = &fmt,
- .dpb_size = dpb_size + p_dec->i_extra_picture_buffers + 1,
+ .dpb_size = 0,
.mouse_event = MouseEvent, .mouse_opaque = p_dec,
};
res = input_resource_StartVout( p_owner->p_resource, vctx, &cfg);
@@ -633,6 +645,12 @@ static int CreateVoutIfNeeded(struct decoder_owner *p_owner,
p_owner->fmt.video.i_chroma = p_dec->fmt_out.i_codec;
vlc_mutex_unlock( &p_owner->lock );
+ if ( p_owner->out_pool != NULL )
+ {
+ picture_pool_Release( p_owner->out_pool );
+ p_owner->out_pool = NULL;
+ }
+
if( p_vout == NULL )
{
msg_Err( p_dec, "failed to create video output" );
@@ -696,7 +714,10 @@ static picture_t *ModuleThread_NewVideoBuffer( decoder_t *p_dec )
struct decoder_owner *p_owner = dec_get_owner( p_dec );
assert( p_owner->p_vout );
- return vout_GetPicture( p_owner->p_vout );
+ picture_t *pic = picture_pool_Wait( p_owner->out_pool );
+ if (pic)
+ picture_Reset( pic );
+ return pic;
}
static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
@@ -870,6 +891,9 @@ static void DecoderThread_AbortPictures( decoder_t *p_dec, bool b_abort )
struct decoder_owner *p_owner = dec_get_owner( p_dec );
vlc_mutex_lock( &p_owner->lock ); // called in DecoderThread
+ if (p_owner->out_pool)
+ picture_pool_Cancel( p_owner->out_pool, b_abort );
+
if( p_owner->p_vout != NULL )
vout_Cancel( p_owner->p_vout, b_abort );
vlc_mutex_unlock( &p_owner->lock );
@@ -2015,6 +2039,11 @@ static void DeleteDecoder( decoder_t * p_dec )
(char*)&p_dec->fmt_in.i_codec );
const enum es_format_category_e i_cat =p_dec->fmt_in.i_cat;
+ if ( p_owner->out_pool )
+ {
+ picture_pool_Release( p_owner->out_pool );
+ p_owner->out_pool = NULL;
+ }
decoder_Clean( p_dec );
if (p_owner->vctx)
@@ -2050,6 +2079,8 @@ static void DeleteDecoder( decoder_t * p_dec )
{
/* Reset the cancel state that was set before joining the decoder
* thread */
+ if (p_owner->out_pool)
+ picture_pool_Cancel( p_owner->out_pool, false );
vout_StopDisplay(vout);
p_owner->vout_thread_started = false;
decoder_Notify(p_owner, on_vout_stopped, vout);
@@ -2234,7 +2265,11 @@ void input_DecoderDelete( decoder_t *p_dec )
* This unblocks the thread, allowing the decoder module to join all its
* worker threads (if any) and the decoder thread to terminate. */
if( p_dec->fmt_in.i_cat == VIDEO_ES && p_owner->p_vout != NULL && p_owner->vout_thread_started )
+ {
+ if (p_owner->out_pool)
+ picture_pool_Cancel( p_owner->out_pool, true );
vout_Cancel( p_owner->p_vout, true );
+ }
vlc_mutex_unlock( &p_owner->lock );
vlc_join( p_owner->thread, NULL );
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index c2857541b0b..70ab417899b 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -2029,7 +2029,7 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
video_format_t original;
VoutFixFormat(&original, cfg->fmt);
- if (vout_ChangeSource(vout, &original, cfg->dpb_size) == 0)
+ if (vout_ChangeSource(vout, &original, 0) == 0)
{
video_format_Clean(&original);
return 0;
--
2.17.1
More information about the vlc-devel
mailing list