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

Lukasz M lukasz.m.luki at gmail.com
Fri Nov 15 00:33:38 CET 2013


On 14 November 2013 12:19, Stefano Sabatini <stefasab at gmail.com> wrote:

> On date Wednesday 2013-11-13 23:40:46 +0100, Lukasz Marek encoded:
> > 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 |   70
> +++++++++++++++++++++++++++++++++++++++++-------------
> >  1 file changed, 53 insertions(+), 17 deletions(-)
> >
> > diff --git a/libavdevice/xv.c b/libavdevice/xv.c
> > index fdc96c9..bfa6ff5 100644
> > --- a/libavdevice/xv.c
> > +++ b/libavdevice/xv.c
> > @@ -50,11 +50,36 @@ typedef struct {
> >      char *display_name;
> >
> >      XvImage* yuv_image;
> > +    int 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;
> > @@ -71,6 +96,14 @@ static int xv_write_header(AVFormatContext *s)
> >          return AVERROR(EINVAL);
> >      }
> >
> > +    xv->image_format = xv_get_tag_from_format(encctx->pix_fmt);
> > +    if (!xv->image_format) {
> > +        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->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);
> > @@ -99,18 +132,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 == xv->image_format) {
> >              break;
> >          }
> >      }
> > @@ -118,7 +144,8 @@ 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);
> >      }
> >
> > @@ -126,7 +153,7 @@ static int xv_write_header(AVFormatContext *s)
> >      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->image_format, 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);
> > @@ -160,13 +187,22 @@ static int xv_write_packet(AVFormatContext *s,
> AVPacket *pkt)
> >      AVPicture pict;
> >      AVCodecContext *ctx = s->streams[0]->codec;
> >
> > -    avpicture_fill(&pict, pkt->data, ctx->pix_fmt, ctx->width,
> ctx->height);
> > -    xv_copy_line(img->height, pict.data[0], &img->data[img->offsets[0]],
> > -                 pict.linesize[0], img->pitches[0]);
> > -    xv_copy_line(img->height / 2, pict.data[1],
> &img->data[img->offsets[1]],
> > -                 pict.linesize[1], img->pitches[1]);
> > -    xv_copy_line(img->height / 2, pict.data[2],
> &img->data[img->offsets[2]],
> > -                 pict.linesize[2], img->pitches[2]);
> > +    if (xv->image_format == MKTAG('I','4','2','0')) {
> > +        avpicture_fill(&pict, pkt->data, ctx->pix_fmt, ctx->width,
> ctx->height);
> > +        xv_copy_line(img->height, pict.data[0],
> &img->data[img->offsets[0]],
> > +                     pict.linesize[0], img->pitches[0]);
> > +        xv_copy_line(img->height / 2, pict.data[1],
> &img->data[img->offsets[1]],
> > +                     pict.linesize[1], img->pitches[1]);
> > +        xv_copy_line(img->height / 2, pict.data[2],
> &img->data[img->offsets[2]],
> > +                     pict.linesize[2], img->pitches[2]);
> > +    } else /* if (xv->image_format == MKTAG('U','Y','V','Y') ||
> > +                  xv->image_format == MKTAG('Y','U','Y','2')) */ {
> > +        if (img->pitches[0] == 2 * img->width)
> > +            memcpy(&img->data[img->offsets[0]], pkt->data,
> img->pitches[0] * img->height);
> > +        else
> > +            xv_copy_line(img->height, pkt->data,
> &img->data[img->offsets[0]],
> > +                         2 * img->width, img->pitches[0]);
> > +    }
>
> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-lavd-xv-add-more-supported-formats.patch
Type: text/x-patch
Size: 4542 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131115/52f1c885/attachment.bin>


More information about the ffmpeg-devel mailing list