[FFmpeg-devel] [PATCH 2/3] lavd/xv: add more supported formats

Stefano Sabatini stefasab at gmail.com
Fri Nov 15 09:51:21 CET 2013


On date Friday 2013-11-15 00:33:38 +0100, Lukasz M encoded:
> On 14 November 2013 12:19, Stefano Sabatini <stefasab at gmail.com> wrote:
[...]
> > This can be simplified by using the more generic (how much slower?)
> > av_copy_image().
> >
> 
> I did that. I haven't tested this format, but I believe performance
> difference will be similar to yuv420p.

> From 3305a98e5a595006539ce98ff7f7da4f21bfc244 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki at gmail.com>
> Date: Wed, 13 Nov 2013 23:40:46 +0100
> Subject: [PATCH 2/3] lavd/xv: add more supported formats
> 
> Add support for following pixel formats:
> - AV_PIX_FMT_UYVY422
> - AV_PIX_FMT_YUYV422
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
> ---
>  libavdevice/xv.c |   52 +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 39 insertions(+), 13 deletions(-)
> 
> diff --git a/libavdevice/xv.c b/libavdevice/xv.c
> index 23c8761..4492df0 100644
> --- a/libavdevice/xv.c
> +++ b/libavdevice/xv.c
> @@ -51,18 +51,43 @@ typedef struct {
>      char *display_name;
>  
>      XvImage* yuv_image;
> +    enum AVPixelFormat image_format;
>      int image_width, image_height;
>      XShmSegmentInfo yuv_shminfo;
>      int xv_port;
>  } XVContext;
>  
> +typedef struct XVTagFormatMap
> +{
> +    int tag;
> +    enum AVPixelFormat format;
> +} XVTagFormatMap;
> +
> +static XVTagFormatMap tag_codec_map[] = {
> +    { MKTAG('I','4','2','0'), AV_PIX_FMT_YUV420P },
> +    { MKTAG('U','Y','V','Y'), AV_PIX_FMT_UYVY422 },
> +    { MKTAG('Y','U','Y','2'), AV_PIX_FMT_YUYV422 },
> +    { 0,                      AV_PIX_FMT_NONE }
> +};
> +
> +static int xv_get_tag_from_format(enum AVPixelFormat format)
> +{
> +    XVTagFormatMap *m = tag_codec_map;
> +    int i;
> +    for (i = 0; m->tag; m = &tag_codec_map[++i]) {
> +        if (m->format == format)
> +            return m->tag;
> +    }
> +    return 0;
> +}
> +
>  static int xv_write_header(AVFormatContext *s)
>  {
>      XVContext *xv = s->priv_data;
>      unsigned int num_adaptors;
>      XvAdaptorInfo *ai;
>      XvImageFormatValues *fv;
> -    int num_formats = 0, j;
> +    int num_formats = 0, j, tag;
>      AVCodecContext *encctx = s->streams[0]->codec;
>  
>      if (   s->nb_streams > 1
> @@ -72,6 +97,14 @@ static int xv_write_header(AVFormatContext *s)
>          return AVERROR(EINVAL);
>      }
>  
> +    if (!(tag = xv_get_tag_from_format(encctx->pix_fmt))) {
> +        av_log(s, AV_LOG_ERROR,
> +               "Unsupported pixel format '%s', only yuv420p, uyvy422, yuyv422 are currently supported\n",
> +               av_get_pix_fmt_name(encctx->pix_fmt));
> +        return AVERROR_PATCHWELCOME;
> +    }
> +    xv->image_format = encctx->pix_fmt;
> +
>      xv->display = XOpenDisplay(xv->display_name);
>      if (!xv->display) {
>          av_log(s, AV_LOG_ERROR, "Could not open the X11 display '%s'\n", xv->display_name);
> @@ -100,18 +133,11 @@ static int xv_write_header(AVFormatContext *s)
>      xv->xv_port = ai[0].base_id;
>      XvFreeAdaptorInfo(ai);
>  
> -    if (encctx->pix_fmt != AV_PIX_FMT_YUV420P) {
> -        av_log(s, AV_LOG_ERROR,
> -               "Unsupported pixel format '%s', only yuv420p is currently supported\n",
> -               av_get_pix_fmt_name(encctx->pix_fmt));
> -        return AVERROR_PATCHWELCOME;
> -    }
> -
>      fv = XvListImageFormats(xv->display, xv->xv_port, &num_formats);
>      if (!fv)
>          return AVERROR_EXTERNAL;
>      for (j = 0; j < num_formats; j++) {
> -        if (fv[j].id == MKTAG('I','4','2','0')) {
> +        if (fv[j].id == tag) {
>              break;
>          }
>      }
> @@ -119,15 +145,15 @@ static int xv_write_header(AVFormatContext *s)
>  
>      if (j >= num_formats) {
>          av_log(s, AV_LOG_ERROR,
> -               "Device does not support pixel format yuv420p, aborting\n");
> +               "Device does not support pixel format %s, aborting\n",
> +               av_get_pix_fmt_name(encctx->pix_fmt));
>          return AVERROR(EINVAL);
>      }
>  
>      xv->gc = XCreateGC(xv->display, xv->window, 0, 0);
>      xv->image_width  = encctx->width;
>      xv->image_height = encctx->height;
> -    xv->yuv_image = XvShmCreateImage(xv->display, xv->xv_port,
> -                                     MKTAG('I','4','2','0'), 0,
> +    xv->yuv_image = XvShmCreateImage(xv->display, xv->xv_port, tag, 0,
>                                       xv->image_width, xv->image_height, &xv->yuv_shminfo);
>      xv->yuv_shminfo.shmid = shmget(IPC_PRIVATE, xv->yuv_image->data_size,
>                                     IPC_CREAT | 0777);
> @@ -157,7 +183,7 @@ static int xv_write_packet(AVFormatContext *s, AVPacket *pkt)
>  
>      avpicture_fill(&pict, pkt->data, ctx->pix_fmt, ctx->width, ctx->height);
>      av_image_copy(data, img->pitches, (const uint8_t **)pict.data, pict.linesize,
> -                  AV_PIX_FMT_YUV420P, img->width, img->height);
> +                  xv->image_format, img->width, img->height);
>  
>      XGetWindowAttributes(xv->display, xv->window, &window_attrs);
>      if (XvShmPutImage(xv->display, xv->xv_port, xv->window, xv->gc,

LGTM, will push it soon.
-- 
FFmpeg = Fancy and Fast Mastodontic Powered Erotic Gnome


More information about the ffmpeg-devel mailing list