Commit 3fd7fd49 authored by Laurent Aimar's avatar Laurent Aimar

Gives the needed DPB size when requesting a vout.

It properly fixes #3526.
parent 3576b1fd
...@@ -151,10 +151,6 @@ ...@@ -151,10 +151,6 @@
/* Number of planes in a picture */ /* Number of planes in a picture */
#define VOUT_MAX_PLANES 5 #define VOUT_MAX_PLANES 5
/* Video heap size - remember that a decompressed picture is big
* (~1 Mbyte) before using huge values */
#define VOUT_MAX_PICTURES 20
/* /*
* Time settings * Time settings
*/ */
......
...@@ -54,6 +54,7 @@ typedef struct { ...@@ -54,6 +54,7 @@ typedef struct {
vout_thread_t *vout; vout_thread_t *vout;
vlc_object_t *input; vlc_object_t *input;
const video_format_t *fmt; const video_format_t *fmt;
unsigned dpb_size;
} vout_configuration_t; } vout_configuration_t;
/** /**
......
...@@ -816,9 +816,10 @@ static vout_thread_t *RequestVout( void *p_private, ...@@ -816,9 +816,10 @@ static vout_thread_t *RequestVout( void *p_private,
aout_instance_t *p_aout = p_private; aout_instance_t *p_aout = p_private;
VLC_UNUSED(b_recycle); VLC_UNUSED(b_recycle);
vout_configuration_t cfg = { vout_configuration_t cfg = {
.vout = p_vout, .vout = p_vout,
.input = NULL, .input = NULL,
.fmt = p_fmt, .fmt = p_fmt,
.dpb_size = 1,
}; };
return vout_Request( p_aout, &cfg ); return vout_Request( p_aout, &cfg );
} }
......
...@@ -2077,7 +2077,7 @@ static void DeleteDecoder( decoder_t * p_dec ) ...@@ -2077,7 +2077,7 @@ static void DeleteDecoder( decoder_t * p_dec )
vout_Reset( p_owner->p_vout ); vout_Reset( p_owner->p_vout );
/* */ /* */
input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, true ); input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, 0, true );
input_SendEventVout( p_owner->p_input ); input_SendEventVout( p_owner->p_input );
} }
...@@ -2157,7 +2157,7 @@ static vout_thread_t *aout_request_vout( void *p_private, ...@@ -2157,7 +2157,7 @@ static vout_thread_t *aout_request_vout( void *p_private,
decoder_t *p_dec = p_private; decoder_t *p_dec = p_private;
input_thread_t *p_input = p_dec->p_owner->p_input; input_thread_t *p_input = p_dec->p_owner->p_input;
p_vout = input_resource_RequestVout( p_input->p->p_resource, p_vout, p_fmt, b_recyle ); p_vout = input_resource_RequestVout( p_input->p->p_resource, p_vout, p_fmt, 1, b_recyle );
input_SendEventVout( p_input ); input_SendEventVout( p_input );
return p_vout; return p_vout;
...@@ -2333,9 +2333,27 @@ static picture_t *vout_new_buffer( decoder_t *p_dec ) ...@@ -2333,9 +2333,27 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
p_owner->p_vout = NULL; p_owner->p_vout = NULL;
vlc_mutex_unlock( &p_owner->lock ); vlc_mutex_unlock( &p_owner->lock );
unsigned dpb_size;
switch( p_dec->fmt_in.i_codec )
{
case VLC_CODEC_H264:
case VLC_CODEC_DIRAC: /* FIXME valid ? */
dpb_size = 18;
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_vout = input_resource_RequestVout( p_owner->p_input->p->p_resource, p_vout = input_resource_RequestVout( p_owner->p_input->p->p_resource,
p_vout, &p_dec->fmt_out.video, true ); p_vout, &p_dec->fmt_out.video,
dpb_size + 1 + DECODER_MAX_BUFFERING_COUNT,
true );
vlc_mutex_lock( &p_owner->lock ); vlc_mutex_lock( &p_owner->lock );
p_owner->p_vout = p_vout; p_owner->p_vout = p_vout;
......
...@@ -205,7 +205,8 @@ static void DisplayVoutTitle( input_resource_t *p_resource, ...@@ -205,7 +205,8 @@ static void DisplayVoutTitle( input_resource_t *p_resource,
free( psz_nowplaying ); free( psz_nowplaying );
} }
static vout_thread_t *RequestVout( input_resource_t *p_resource, static vout_thread_t *RequestVout( input_resource_t *p_resource,
vout_thread_t *p_vout, video_format_t *p_fmt, vout_thread_t *p_vout,
video_format_t *p_fmt, unsigned dpb_size,
bool b_recycle ) bool b_recycle )
{ {
vlc_assert_locked( &p_resource->lock ); vlc_assert_locked( &p_resource->lock );
...@@ -243,9 +244,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, ...@@ -243,9 +244,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource,
/* */ /* */
vout_configuration_t cfg = { vout_configuration_t cfg = {
.vout = p_vout, .vout = p_vout,
.input = VLC_OBJECT(p_resource->p_input), .input = VLC_OBJECT(p_resource->p_input),
.fmt = p_fmt, .fmt = p_fmt,
.dpb_size = dpb_size,
}; };
p_vout = vout_Request( p_resource->p_input, &cfg ); p_vout = vout_Request( p_resource->p_input, &cfg );
if( !p_vout ) if( !p_vout )
...@@ -281,9 +283,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource, ...@@ -281,9 +283,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource,
vout_FlushSubpictureChannel( p_vout, -1 ); vout_FlushSubpictureChannel( p_vout, -1 );
vout_configuration_t cfg = { vout_configuration_t cfg = {
.vout = p_vout, .vout = p_vout,
.input = NULL, .input = NULL,
.fmt = p_fmt, .fmt = p_fmt,
.dpb_size = 0,
}; };
p_resource->p_vout_free = vout_Request( p_resource->p_input, &cfg ); p_resource->p_vout_free = vout_Request( p_resource->p_input, &cfg );
} }
...@@ -467,10 +470,12 @@ input_resource_t *input_resource_Detach( input_resource_t *p_resource ) ...@@ -467,10 +470,12 @@ input_resource_t *input_resource_Detach( input_resource_t *p_resource )
} }
vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource, vout_thread_t *input_resource_RequestVout( input_resource_t *p_resource,
vout_thread_t *p_vout, video_format_t *p_fmt, bool b_recycle ) vout_thread_t *p_vout,
video_format_t *p_fmt, unsigned dpb_size,
bool b_recycle )
{ {
vlc_mutex_lock( &p_resource->lock ); vlc_mutex_lock( &p_resource->lock );
vout_thread_t *p_ret = RequestVout( p_resource, p_vout, p_fmt, b_recycle ); vout_thread_t *p_ret = RequestVout( p_resource, p_vout, p_fmt, dpb_size, b_recycle );
vlc_mutex_unlock( &p_resource->lock ); vlc_mutex_unlock( &p_resource->lock );
return p_ret; return p_ret;
...@@ -488,7 +493,7 @@ void input_resource_HoldVouts( input_resource_t *p_resource, vout_thread_t ***pp ...@@ -488,7 +493,7 @@ void input_resource_HoldVouts( input_resource_t *p_resource, vout_thread_t ***pp
void input_resource_TerminateVout( input_resource_t *p_resource ) void input_resource_TerminateVout( input_resource_t *p_resource )
{ {
input_resource_RequestVout( p_resource, NULL, NULL, false ); input_resource_RequestVout( p_resource, NULL, NULL, 0, false );
} }
bool input_resource_HasVout( input_resource_t *p_resource ) bool input_resource_HasVout( input_resource_t *p_resource )
{ {
......
...@@ -67,7 +67,7 @@ aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource ); ...@@ -67,7 +67,7 @@ aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource );
/** /**
* This function handles vout request. * This function handles vout request.
*/ */
vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, bool b_recycle ); vout_thread_t *input_resource_RequestVout( input_resource_t *, vout_thread_t *, video_format_t *, unsigned dpb_size, bool b_recycle );
/** /**
* This function return one of the current vout if any. * This function return one of the current vout if any.
......
...@@ -112,6 +112,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object, ...@@ -112,6 +112,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
vout->p = (vout_thread_sys_t*)&vout[1]; vout->p = (vout_thread_sys_t*)&vout[1];
vout->p->original = original; vout->p->original = original;
vout->p->dpb_size = cfg->dpb_size;
vout_control_Init(&vout->p->control); vout_control_Init(&vout->p->control);
vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_INIT); vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_INIT);
...@@ -1027,8 +1028,11 @@ static int ThreadReinit(vout_thread_t *vout, ...@@ -1027,8 +1028,11 @@ static int ThreadReinit(vout_thread_t *vout,
ThreadClean(vout); ThreadClean(vout);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if (video_format_IsSimilar(&original, &vout->p->original)) if (video_format_IsSimilar(&original, &vout->p->original)) {
return VLC_SUCCESS; if (cfg->dpb_size <= vout->p->dpb_size)
return VLC_SUCCESS;
msg_Warn(vout, "DPB need to be increased");
}
vout_display_state_t state; vout_display_state_t state;
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
...@@ -1045,6 +1049,7 @@ static int ThreadReinit(vout_thread_t *vout, ...@@ -1045,6 +1049,7 @@ static int ThreadReinit(vout_thread_t *vout,
* and I am not sure what to do */ * and I am not sure what to do */
vout->p->original = original; vout->p->original = original;
vout->p->dpb_size = cfg->dpb_size;
if (ThreadStart(vout, &state)) { if (ThreadStart(vout, &state)) {
ThreadClean(vout); ThreadClean(vout);
return VLC_EGENERIC; return VLC_EGENERIC;
......
...@@ -40,6 +40,14 @@ ...@@ -40,6 +40,14 @@
#include "statistic.h" #include "statistic.h"
#include "chrono.h" #include "chrono.h"
/* It should be high enough to absorbe jitter due to difficult picture(s)
* to decode but not too high as memory is not that cheap.
*
* It can be made lower at compilation time if needed, but performance
* may be degraded.
*/
#define VOUT_MAX_PICTURES (20)
/* */ /* */
struct vout_thread_sys_t struct vout_thread_sys_t
{ {
...@@ -51,6 +59,7 @@ struct vout_thread_sys_t ...@@ -51,6 +59,7 @@ struct vout_thread_sys_t
/* */ /* */
video_format_t original; /* Original format ie coming from the decoder */ video_format_t original; /* Original format ie coming from the decoder */
unsigned dpb_size;
/* Snapshot interface */ /* Snapshot interface */
vout_snapshot_t snapshot; vout_snapshot_t snapshot;
......
...@@ -36,14 +36,6 @@ ...@@ -36,14 +36,6 @@
#include "vout_internal.h" #include "vout_internal.h"
#include "display.h" #include "display.h"
/* Minimum number of direct pictures the video output will accept without
* creating additional pictures in system memory */
#ifdef OPTIMIZE_MEMORY
# define VOUT_MIN_DIRECT_PICTURES (VOUT_MAX_PICTURES/2)
#else
# define VOUT_MIN_DIRECT_PICTURES (3*VOUT_MAX_PICTURES/4)
#endif
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -126,27 +118,42 @@ int vout_InitWrapper(vout_thread_t *vout) ...@@ -126,27 +118,42 @@ int vout_InitWrapper(vout_thread_t *vout)
vout_display_t *vd = sys->display.vd; vout_display_t *vd = sys->display.vd;
video_format_t source = vd->source; video_format_t source = vd->source;
/* XXX For non dr case, the current vout implementation force us to
* create at most 1 direct picture (otherwise the buffers will be kept
* referenced even through the Init/End.
*/
sys->display.use_dr = !vout_IsDisplayFiltered(vd); sys->display.use_dr = !vout_IsDisplayFiltered(vd);
const bool allow_dr = !vd->info.has_pictures_invalid && sys->display.use_dr; const bool allow_dr = !vd->info.has_pictures_invalid && sys->display.use_dr;
const unsigned private_picture = 3; /* XXX 2 for filter, 1 for SPU */
picture_pool_t *display_pool = vout_display_Pool(vd, allow_dr ? VOUT_MAX_PICTURES : 3); const unsigned display_picture = 1; /* Minimum number of display picture */
if (allow_dr && picture_pool_GetSize(display_pool) >= VOUT_MIN_DIRECT_PICTURES) { const unsigned decoder_picture = 1 + sys->dpb_size;
const unsigned kept_picture = 1; /* last displayed picture */
const unsigned reserved_picture = display_picture +
private_picture +
kept_picture;
picture_pool_t *display_pool =
vout_display_Pool(vd, allow_dr ? __MAX(VOUT_MAX_PICTURES,
reserved_picture + decoder_picture) : 3);
if (allow_dr &&
picture_pool_GetSize(display_pool) >= reserved_picture + decoder_picture) {
sys->dpb_size = picture_pool_GetSize(display_pool) - reserved_picture - kept_picture;
sys->decoder_pool = display_pool; sys->decoder_pool = display_pool;
sys->display_pool = display_pool; sys->display_pool = display_pool;
sys->is_decoder_pool_slow = vd->info.is_slow; sys->is_decoder_pool_slow = vd->info.is_slow;
} else if (!sys->decoder_pool) { } else if (!sys->decoder_pool) {
sys->decoder_pool = picture_pool_NewFromFormat(&source, VOUT_MAX_PICTURES); sys->decoder_pool =
picture_pool_NewFromFormat(&source,
__MAX(VOUT_MAX_PICTURES,
private_picture + kept_picture + decoder_picture));
if (allow_dr) {
msg_Warn(vout, "Not enough direct buffers, using system memory");
sys->dpb_size = 0;
} else {
sys->dpb_size = picture_pool_GetSize(display_pool) - private_picture - kept_picture;
}
if (sys->display.use_dr) if (sys->display.use_dr)
sys->display_pool = display_pool; sys->display_pool = display_pool;
else else
sys->display_pool = picture_pool_Reserve(sys->decoder_pool, 1);; sys->display_pool = picture_pool_Reserve(sys->decoder_pool, display_picture);
sys->is_decoder_pool_slow = false; sys->is_decoder_pool_slow = false;
} }
sys->private_pool = picture_pool_Reserve(sys->decoder_pool, 3); /* XXX 2 for filter, 1 for SPU */ sys->private_pool = picture_pool_Reserve(sys->decoder_pool, private_picture);
sys->display.filtered = NULL; sys->display.filtered = NULL;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment