diff options
author | Lukasz Marek <lukasz.m.luki@gmail.com> | 2013-11-13 23:40:46 +0100 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2013-11-15 09:56:58 +0100 |
commit | 57bca5a2b613a1598db93218a1f7d9628cea1966 (patch) | |
tree | a6fcf7726bb1d8cb0ea5f4e87cf8be756b75f29c /libavdevice | |
parent | 5d8619595b84e1edf7add6e8e348e7c5767d3d3f (diff) | |
download | ffmpeg-57bca5a2b613a1598db93218a1f7d9628cea1966.tar.gz |
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@gmail.com>
Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
Diffstat (limited to 'libavdevice')
-rw-r--r-- | libavdevice/xv.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/libavdevice/xv.c b/libavdevice/xv.c index 23c876114b..4492df02d3 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, |