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 @@
/* Number of planes in a picture */
#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
*/
......
......@@ -54,6 +54,7 @@ typedef struct {
vout_thread_t *vout;
vlc_object_t *input;
const video_format_t *fmt;
unsigned dpb_size;
} vout_configuration_t;
/**
......
......@@ -816,9 +816,10 @@ static vout_thread_t *RequestVout( void *p_private,
aout_instance_t *p_aout = p_private;
VLC_UNUSED(b_recycle);
vout_configuration_t cfg = {
.vout = p_vout,
.input = NULL,
.fmt = p_fmt,
.vout = p_vout,
.input = NULL,
.fmt = p_fmt,
.dpb_size = 1,
};
return vout_Request( p_aout, &cfg );
}
......
......@@ -2077,7 +2077,7 @@ static void DeleteDecoder( decoder_t * p_dec )
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 );
}
......@@ -2157,7 +2157,7 @@ static vout_thread_t *aout_request_vout( void *p_private,
decoder_t *p_dec = p_private;
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 );
return p_vout;
......@@ -2333,9 +2333,27 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
p_owner->p_vout = NULL;
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, &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 );
p_owner->p_vout = p_vout;
......
......@@ -205,7 +205,8 @@ static void DisplayVoutTitle( input_resource_t *p_resource,
free( psz_nowplaying );
}
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 )
{
vlc_assert_locked( &p_resource->lock );
......@@ -243,9 +244,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource,
/* */
vout_configuration_t cfg = {
.vout = p_vout,
.input = VLC_OBJECT(p_resource->p_input),
.fmt = p_fmt,
.vout = p_vout,
.input = VLC_OBJECT(p_resource->p_input),
.fmt = p_fmt,
.dpb_size = dpb_size,
};
p_vout = vout_Request( p_resource->p_input, &cfg );
if( !p_vout )
......@@ -281,9 +283,10 @@ static vout_thread_t *RequestVout( input_resource_t *p_resource,
vout_FlushSubpictureChannel( p_vout, -1 );
vout_configuration_t cfg = {
.vout = p_vout,
.input = NULL,
.fmt = p_fmt,
.vout = p_vout,
.input = NULL,
.fmt = p_fmt,
.dpb_size = 0,
};
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 )
}
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 );
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 );
return p_ret;
......@@ -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 )
{
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 )
{
......
......@@ -67,7 +67,7 @@ aout_instance_t *input_resource_HoldAout( input_resource_t *p_resource );
/**
* 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.
......
......@@ -112,6 +112,7 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
vout->p = (vout_thread_sys_t*)&vout[1];
vout->p->original = original;
vout->p->dpb_size = cfg->dpb_size;
vout_control_Init(&vout->p->control);
vout_control_PushVoid(&vout->p->control, VOUT_CONTROL_INIT);
......@@ -1027,8 +1028,11 @@ static int ThreadReinit(vout_thread_t *vout,
ThreadClean(vout);
return VLC_EGENERIC;
}
if (video_format_IsSimilar(&original, &vout->p->original))
return VLC_SUCCESS;
if (video_format_IsSimilar(&original, &vout->p->original)) {
if (cfg->dpb_size <= vout->p->dpb_size)
return VLC_SUCCESS;
msg_Warn(vout, "DPB need to be increased");
}
vout_display_state_t state;
memset(&state, 0, sizeof(state));
......@@ -1045,6 +1049,7 @@ static int ThreadReinit(vout_thread_t *vout,
* and I am not sure what to do */
vout->p->original = original;
vout->p->dpb_size = cfg->dpb_size;
if (ThreadStart(vout, &state)) {
ThreadClean(vout);
return VLC_EGENERIC;
......
......@@ -40,6 +40,14 @@
#include "statistic.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
{
......@@ -51,6 +59,7 @@ struct vout_thread_sys_t
/* */
video_format_t original; /* Original format ie coming from the decoder */
unsigned dpb_size;
/* Snapshot interface */
vout_snapshot_t snapshot;
......
......@@ -36,14 +36,6 @@
#include "vout_internal.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
*****************************************************************************/
......@@ -126,27 +118,42 @@ int vout_InitWrapper(vout_thread_t *vout)
vout_display_t *vd = sys->display.vd;
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);
const bool allow_dr = !vd->info.has_pictures_invalid && sys->display.use_dr;
picture_pool_t *display_pool = vout_display_Pool(vd, allow_dr ? VOUT_MAX_PICTURES : 3);
if (allow_dr && picture_pool_GetSize(display_pool) >= VOUT_MIN_DIRECT_PICTURES) {
const unsigned private_picture = 3; /* XXX 2 for filter, 1 for SPU */
const unsigned display_picture = 1; /* Minimum number of display picture */
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->display_pool = display_pool;
sys->is_decoder_pool_slow = vd->info.is_slow;
} 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)
sys->display_pool = display_pool;
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->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;
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