[FFmpeg-devel] [PATCH] lavd/xv: handle delete window message

Nicolas George george at nsup.org
Sun Jun 1 15:43:00 CEST 2014


Le primidi 11 prairial, an CCXXII, Lukasz Marek a écrit :
> From c6745beaddad2ddd4ed7c18e7705bd79e95efcf5 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> Date: Tue, 27 May 2014 22:57:26 +0200
> Subject: [PATCH] lavd/xv: handle delete window message
> 
> User may close X11 window by close button on tray.
> FFmpeg leaves in graceless way.
> This commit detects it and return EPIPE error.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> ---
>  libavdevice/xv.c |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/libavdevice/xv.c b/libavdevice/xv.c
> index d1f8907..a702a50 100644
> --- a/libavdevice/xv.c
> +++ b/libavdevice/xv.c
> @@ -58,6 +58,7 @@ typedef struct {
>      int image_width, image_height;
>      XShmSegmentInfo yuv_shminfo;
>      int xv_port;
> +    Atom wm_delete_message;
>  } XVContext;
>  
>  typedef struct XVTagFormatMap
> @@ -156,6 +157,8 @@ static int xv_write_header(AVFormatContext *s)
>              }
>          }
>          XStoreName(xv->display, xv->window, xv->window_title);
> +        xv->wm_delete_message = XInternAtom(xv->display, "WM_DELETE_WINDOW", False);
> +        XSetWMProtocols(xv->display, xv->window, &xv->wm_delete_message, 1);
>          XMapWindow(xv->display, xv->window);
>      } else
>          xv->window = xv->window_id;
> @@ -297,6 +300,22 @@ static int write_picture(AVFormatContext *s, AVPicture *pict)
>          img->data + img->offsets[1],
>          img->data + img->offsets[2]
>      };
> +
> +    /* Check messages. Window might get closed. */
> +    if (!xv->window_id) {
> +        XEvent event;

> +        int cnt = XPending(xv->display);
> +        while (cnt--) {
> +            XNextEvent(xv->display, &event);

Most of the time, this kind of loop just looks like that:

	while (XPending(display)) {

That is slightly simpler and possibly more robust in case some event handler
causes events to be received.

> +            if (event.type == ClientMessage) {
> +                if (event.xclient.data.l[0] == xv->wm_delete_message) {

You could combine the two tests into a single one.

> +                    av_log(xv, AV_LOG_DEBUG, "Window close event.\n");
> +                    return AVERROR(EPIPE);

I am afraid the proper behaviour is more complex than that, but this version
is probably a good start until we make devices' behaviour uniform.

> +                }
> +            }
> +        }
> +    }
> +
>      av_image_copy(data, img->pitches, (const uint8_t **)pict->data, pict->linesize,
>                    xv->image_format, img->width, img->height);
>      return xv_repaint(s);

Globally LGTM, thanks.

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140601/5affc20e/attachment.asc>


More information about the ffmpeg-devel mailing list