[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