[FFmpeg-cvslog] lavd/xv: add more supported formats

Lukasz Marek git at videolan.org
Fri Nov 15 10:00:24 CET 2013


ffmpeg | branch: master | Lukasz Marek <lukasz.m.luki at gmail.com> | Wed Nov 13 23:40:46 2013 +0100| [57bca5a2b613a1598db93218a1f7d9628cea1966] | committer: Stefano Sabatini

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>
Signed-off-by: Stefano Sabatini <stefasab at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=57bca5a2b613a1598db93218a1f7d9628cea1966
---

 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,



More information about the ffmpeg-cvslog mailing list