[vlc-devel] [PATCH 04/11] Display: Support rotated movies.

Rémi Denis-Courmont remi at remlab.net
Thu Mar 6 21:35:55 CET 2014


Le jeudi 6 mars 2014, 01:12:25 Matthias Keiser a écrit :
> ---
>  include/vlc_vout_display.h |  13 ++++++
>  src/libvlccore.sym         |   1 +
>  src/video_output/display.c | 101
> +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 103
> insertions(+), 12 deletions(-)
> 
> diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
> index d99cf7e..f5f6817 100644
> --- a/include/vlc_vout_display.h
> +++ b/include/vlc_vout_display.h
> @@ -436,5 +436,18 @@ typedef struct {
>   */
>  VLC_API void vout_display_PlacePicture(vout_display_place_t *place, const
> video_format_t *source, const vout_display_cfg_t *cfg, bool do_clipping);
> 
> +
> +/**
> + * Helper function that applies the necessary transforms to the mouse
> position + * and then calls vout_display_SendEventMouseMoved.
> + *
> + * \param vd vout_display_t.
> + * \param orient_display The orientation of the picture as seen on screen
> (probably ORIENT_NORMAL). + * \param m_x Mouse x position (relative to
> place, origin is top left). + * \param m_y Mouse y position (relative to
> place, origin is top left). + * \param place Place of the picture.
> + */
> +VLC_API void vout_display_SendMouseMovedDisplayCoordinates(vout_display_t
> *vd, video_orientation_t orient_display, int m_x, int m_y, +               
>                                            vout_display_place_t *place);
> #endif /* VLC_VOUT_DISPLAY_H */
> 
> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> index e2c2008..e6cbaf9 100644
> --- a/src/libvlccore.sym
> +++ b/src/libvlccore.sym
> @@ -635,6 +635,7 @@ vout_SetDisplayAspect
>  vout_SetDisplayCrop
>  vout_display_GetDefaultDisplaySize
>  vout_display_PlacePicture
> +vout_display_SendMouseMovedDisplayCoordinates
>  xml_Create
>  text_style_Copy
>  text_style_Delete
> diff --git a/src/video_output/display.c b/src/video_output/display.c
> index 906bca0..967133f 100644
> --- a/src/video_output/display.c
> +++ b/src/video_output/display.c
> @@ -197,6 +197,13 @@ void vout_display_GetDefaultDisplaySize(unsigned
> *width, unsigned *height,
> 
>      *width  = *width  * cfg->zoom.num / cfg->zoom.den;
>      *height = *height * cfg->zoom.num / cfg->zoom.den;
> +
> +    if (ORIENT_IS_SWAP(source->orientation)) {
> +
> +        unsigned store = *width;
> +        *width = *height;
> +        *height = store;
> +    }
>  }
> 
>  /* */
> @@ -214,6 +221,10 @@ void vout_display_PlacePicture(vout_display_place_t
> *place, unsigned display_width;
>      unsigned display_height;
> 
> +    video_format_t source_rot;
> +    video_format_ApplyRotation(source, &source_rot);
> +    source = &source_rot;
> +
>      if (cfg->is_display_filled) {
>          display_width  = cfg->display.width;
>          display_height = cfg->display.height;
> @@ -273,6 +284,62 @@ void vout_display_PlacePicture(vout_display_place_t
> *place, }
>  }
> 
> +void vout_display_SendMouseMovedDisplayCoordinates(vout_display_t *vd,
> video_orientation_t orient_display, int m_x, int m_y, vout_display_place_t
> *place) +{
> +    video_format_t source_rot = vd->source;
> +    video_format_TransformTo(&source_rot, orient_display);
> +
> +    if (place->width > 0 && place->height > 0) {
> +
> +        int x = (int)(source_rot.i_x_offset +
> +                            (int64_t)(m_x - place->x) *
> source_rot.i_visible_width / place->width); +        int y =
> (int)(source_rot.i_y_offset +
> +                            (int64_t)(m_y - place->y) *
> source_rot.i_visible_height/ place->height); +
> +        video_transform_t transform =
> video_format_GetTransform(vd->source.orientation, orient_display); +
> +        int store;
> +
> +        switch (transform) {
> +
> +            case TRANSFORM_R90:
> +                store = x;
> +                x = y;
> +                y = vd->source.i_visible_height - store;
> +                break;
> +            case TRANSFORM_R180:
> +                x = vd->source.i_visible_width - x;
> +                y = vd->source.i_visible_height - y;
> +                break;
> +            case TRANSFORM_R270:
> +                store = x;
> +                x = vd->source.i_visible_width - y;
> +                y = store;
> +                break;
> +            case TRANSFORM_HFLIP:
> +                x = vd->source.i_visible_width - x;
> +                break;
> +            case TRANSFORM_VFLIP:
> +                y = vd->source.i_visible_height - y;
> +                break;
> +            case TRANSFORM_TRANSPOSE:
> +                store = x;
> +                x = y;
> +                y = store;
> +                break;
> +            case TRANSFORM_ANTI_TRANSPOSE:
> +                store = x;
> +                x = vd->source.i_visible_width - y;
> +                y = vd->source.i_visible_height - store;
> +                break;
> +            default:
> +                break;
> +        }
> +
> +        vout_display_SendEventMouseMoved (vd, x, y);
> +    }
> +}
> +
>  struct vout_display_owner_sys_t {
>      vout_thread_t   *vout;
>      bool            is_wrapper;  /* Is the current display a wrapper */
> @@ -385,6 +452,11 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
> v_dst.i_sar_num = 0;
>      v_dst.i_sar_den = 0;
> 
> +    es_format_t src;
> +    es_format_InitFromVideo(&src, &v_src);
> +
> +    filter_t *filter;
> +
>      video_format_t v_dst_cmp = v_dst;
>      if ((v_src.i_chroma == VLC_CODEC_J420 && v_dst.i_chroma ==
> VLC_CODEC_I420) || (v_src.i_chroma == VLC_CODEC_J422 && v_dst.i_chroma ==
> VLC_CODEC_I422) || @@ -393,34 +465,39 @@ static void
> VoutDisplayCreateRender(vout_display_t *vd) v_dst_cmp.i_chroma =
> v_src.i_chroma;
> 
>      const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0;
> -    if (!convert)
> +
> +    if (!convert) {
> +        es_format_Clean(&src);

Is this (and all other) for the sake of the principle, because I think it is a 
no-op. Now that the logic was moved to chain, are you sure you need all this 
snippet?

>          return;
> +    }
> 
>      msg_Dbg(vd, "A filter to adapt decoder to display is needed");
> 
> -    osys->filters = filter_chain_New(vd, "video filter2", false,
> -                                     FilterAllocationInit,
> -                                     FilterAllocationClean, vd);
> -    assert(osys->filters); /* TODO critical */
> -
>      /* */
> -    es_format_t src;
> -    es_format_InitFromVideo(&src, &v_src);
> +    if (!osys->filters)
> +        osys->filters = filter_chain_New(vd, "video filter2", true,
> +                                         FilterAllocationInit,
> +                                         FilterAllocationClean, vd);
> 
> -    /* */
> -    es_format_t dst;
> +    assert(osys->filters); /* TODO critical */
> 
> -    filter_t *filter;
>      for (int i = 0; i < 1 + (v_dst_cmp.i_chroma != v_dst.i_chroma); i++) {
> 
> +        es_format_t dst;
> +
>          es_format_InitFromVideo(&dst, i == 0 ? &v_dst : &v_dst_cmp);
> 
> -        filter_chain_Reset(osys->filters, &src, &dst);
>          filter = filter_chain_AppendFilter(osys->filters,
>                                             NULL, NULL, &src, &dst);
> +
> +        es_format_Clean(&dst);

> +
>          if (filter)
>              break;
>      }
> +
> +    es_format_Clean(&src);
> +
>      if (!filter)
>          msg_Err(vd, "Failed to adapt decoder format to display");
>  }

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list