[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