Browse Source

vout: foward vout state through callbacks

Alexandre Janniaux 5 years ago
parent
commit
a2c8a003f3
  1. 20
      include/vlc_vout.h
  2. 46
      src/input/decoder.c
  3. 42
      src/input/resource.c
  4. 5
      src/input/resource.h
  5. 7
      src/video_output/video_output.c

20
include/vlc_vout.h

@ -29,8 +29,20 @@
#include "vlc_picture.h"
#include "vlc_subpicture.h"
enum vout_thread_state
{
VOUT_THREAD_STATE_STOPPED,
VOUT_THREAD_STATE_STARTED,
};
struct vlc_video_output_callbacks
{
/**
* Report a change on the vout state.
*/
void (*on_state_changed)(vout_thread_t *vout,
enum vout_thread_state state, void *owner);
/* Event triggered when the first frame of the vout is being displayed. */
void (*first_frame_reported)(vout_thread_t *vout, void *owner);
void (*captions_to_display)(const void *, size_t, void *owner);
@ -68,6 +80,14 @@ struct vout_thread_t {
const struct vlc_video_output_callbacks *cbs;
};
static inline void vout_ReportStateChange(
struct vout_thread_t *vout, enum vout_thread_state state)
{
if (vout->cbs && vout->cbs->on_state_changed)
vout->cbs->on_state_changed(vout, state, vout->owner);
}
/* Alignment flags */
#define VOUT_ALIGN_LEFT 0x0001
#define VOUT_ALIGN_RIGHT 0x0002

46
src/input/decoder.c

@ -35,6 +35,7 @@
#include <vlc_block.h>
#include <vlc_vout.h>
#include <vlc_aout.h>
#include <vlc_vout.h>
#include <vlc_sout.h>
#include <vlc_codec.h>
#include <vlc_spu.h>
@ -408,6 +409,22 @@ static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
static int CreateVoutIfNeeded(vlc_input_decoder_t *);
static void decoder_vout_on_state_changed(
vout_thread_t *vout, enum vout_thread_state state, void *opaque)
{
vlc_input_decoder_t *p_owner = opaque;
if (state == VOUT_THREAD_STATE_STARTED)
{
vlc_fifo_Lock( p_owner->p_fifo );
p_owner->reset_out_state = true;
vlc_fifo_Unlock( p_owner->p_fifo );
decoder_Notify(p_owner, on_vout_started, vout, p_owner->vout_order);
}
else
decoder_Notify(p_owner, on_vout_stopped, vout);
}
static void decoder_vout_on_frame_displayed(
vout_thread_t *vout, vlc_tick_t pts, void *opaque)
{
@ -483,8 +500,10 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
vlc_mutex_unlock( &p_owner->lock );
}
static const struct vlc_video_output_callbacks vout_thread_cbs =
{
.on_state_changed = decoder_vout_on_state_changed,
.on_frame_displayed = decoder_vout_on_frame_displayed,
.captions_to_display = decoder_vout_captions_to_display,
};
@ -502,22 +521,12 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
bool has_started;
vout_thread_t *p_vout =
input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL,
&has_started);
input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL);
if (p_vout != NULL)
{
vlc_mutex_lock( &p_owner->lock );
p_owner->vout_started = true;
vlc_mutex_unlock( &p_owner->lock );
if (has_started)
{
vlc_fifo_Lock( p_owner->p_fifo );
p_owner->reset_out_state = true;
vlc_fifo_Unlock( p_owner->p_fifo );
decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
}
return 0;
}
@ -594,7 +603,7 @@ static int CreateVoutIfNeeded(vlc_input_decoder_t *p_owner)
enum vlc_vout_order order;
const vout_configuration_t cfg = { .vout = p_vout, .fmt = NULL };
p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order, NULL );
p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order );
vlc_mutex_lock( &p_owner->lock );
p_owner->p_vout = p_vout;
@ -2051,18 +2060,7 @@ static void DeleteDecoder( vlc_input_decoder_t *p_owner )
vout_thread_t *vout = p_owner->p_vout;
if (vout != NULL)
{
/* Hold the vout since PutVout will likely release it and a
* last reference is needed for notify callbacks */
vout_Hold(vout);
bool has_stopped;
input_resource_PutVout(p_owner->p_resource, vout, &has_stopped);
if (has_stopped)
decoder_Notify(p_owner, on_vout_stopped, vout);
vout_Release(vout);
}
input_resource_PutVout(p_owner->p_resource, vout);
break;
}
case SPU_ES:

42
src/input/resource.c

@ -363,20 +363,13 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in
}
static void input_resource_PutVoutLocked(input_resource_t *p_resource,
vout_thread_t *vout, bool *has_stopped)
vout_thread_t *vout)
{
assert(vout != NULL);
struct vout_resource *vout_rsc = resource_GetVoutRsc(p_resource, vout);
assert(vout_rsc != NULL);
if (has_stopped != NULL)
*has_stopped = vout_rsc->started;
if (vout_rsc->started)
{
vout_StopDisplay(vout_rsc->vout);
vout_rsc->started = false;
}
vout_StopDisplay(vout_rsc->vout);
if (vout_rsc == resource_GetFirstVoutRsc(p_resource))
{
@ -401,10 +394,10 @@ static void input_resource_PutVoutLocked(input_resource_t *p_resource,
}
void input_resource_PutVout(input_resource_t *p_resource,
vout_thread_t *vout, bool *stopped)
vout_thread_t *vout)
{
vlc_mutex_lock( &p_resource->lock );
input_resource_PutVoutLocked( p_resource, vout, stopped );
input_resource_PutVoutLocked( p_resource, vout);
vlc_mutex_unlock( &p_resource->lock );
}
@ -456,15 +449,11 @@ RequestVoutRsc(input_resource_t *p_resource)
vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
vlc_video_context *vctx,
const vout_configuration_t *cfg,
enum vlc_vout_order *order,
bool *has_started)
enum vlc_vout_order *order)
{
vlc_mutex_lock( &p_resource->lock );
struct vout_resource *vout_rsc = NULL;
if (has_started != NULL)
*has_started = false;
vout_configuration_t dcfg = *cfg;
if (dcfg.vout == NULL)
{
@ -500,27 +489,15 @@ vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
return dcfg.vout;
}
if (vout_rsc->started)
{
assert(cfg->vout != NULL);
int ret = vout_ChangeSource(dcfg.vout, dcfg.fmt);
if (ret == 0)
{
vlc_mutex_unlock(&p_resource->lock);
return dcfg.vout;
}
}
if (vout_Request(&dcfg, vctx, p_resource->p_input)) {
input_resource_PutVoutLocked(p_resource, dcfg.vout, NULL);
vout_rsc->started = false;
input_resource_PutVoutLocked(p_resource, dcfg.vout);
vlc_mutex_unlock(&p_resource->lock);
return NULL;
}
vout_rsc->started = true;
if (has_started != NULL)
*has_started = true;
#if 0
/* TODO: move this to input */
DisplayVoutTitle(p_resource, cfg->vout);
/* Send original viewpoint to the input in order to update other ESes */
@ -530,6 +507,7 @@ vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
input_ControlPush(p_resource->p_input, INPUT_CONTROL_SET_INITIAL_VIEWPOINT,
&param);
}
#endif
vlc_mutex_unlock( &p_resource->lock );
return dcfg.vout;

5
src/input/resource.h

@ -40,9 +40,8 @@ void input_resource_PutSout(input_resource_t *, sout_instance_t *);
vout_thread_t *input_resource_RequestVout(input_resource_t *, vlc_video_context *,
const vout_configuration_t *,
enum vlc_vout_order *order,
bool *has_started);
void input_resource_PutVout(input_resource_t *, vout_thread_t *, bool *has_stopped);
enum vlc_vout_order *order);
void input_resource_PutVout(input_resource_t *, vout_thread_t *);
/**
* This function returns one of the current vout if any.

7
src/video_output/video_output.c

@ -2684,6 +2684,8 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
assert(cfg->fmt != NULL);
assert(cfg->clock != NULL);
/* TODO: locking */
if (!VoutCheckFormat(cfg->fmt))
/* don't stop the display and keep sys->original */
return -1;
@ -2711,7 +2713,10 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
vlc_mutex_unlock(&sys->window_lock);
if (sys->display != NULL)
{
vout_StopDisplay(cfg->vout);
vout_ReportStateChange(cfg->vout, VOUT_THREAD_STATE_STOPPED);
}
vout_ReinitInterlacingSupport(cfg->vout, &sys->private);
@ -2728,6 +2733,7 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
vout_DisableWindow(vout);
return -1;
}
atomic_store(&sys->control_is_terminated, false);
if (vlc_clone(&sys->thread, Thread, vout, VLC_THREAD_PRIORITY_OUTPUT)) {
vout_ReleaseDisplay(vout);
@ -2738,6 +2744,7 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
if (input != NULL && sys->spu)
spu_Attach(sys->spu, input);
vout_IntfReinit(cfg->vout);
vout_ReportStateChange(cfg->vout, VOUT_THREAD_STATE_STARTED);
end:
cfg->vout->owner = cfg->video.opaque;

Loading…
Cancel
Save