diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-05-27 23:47:05 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-05-27 23:48:22 +0200 |
commit | 8381ab143779d25611a1bb05d674bc39fe940f77 (patch) | |
tree | 74773be2c947475433dcc47898aec49a0c4b198b /libavdevice/x11grab.c | |
parent | b8773e44d56667edea2d68d067d0c156522ca304 (diff) | |
parent | 79aeade6f6f8fbd7ce1da619fdd475e5db88ae24 (diff) | |
download | ffmpeg-8381ab143779d25611a1bb05d674bc39fe940f77.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (29 commits)
ARM: disable ff_vector_fmul_vfp on VFPv3 systems
ARM: check for VFPv3
swscale: Remove unused variables in x86 code.
doc: Drop DJGPP section, Libav now compiles out-of-the-box on FreeDOS.
x86: Add appropriate ifdefs around certain AVX functions.
cmdutils: use sws_freeContext() instead of av_freep().
swscale: delay allocation of formatConvBuffer().
swscale: fix build with --disable-swscale-alpha.
movenc: Deprecate the global RTP hinting flag, use a private AVOption instead
movenc: Add an AVClass for setting muxer specific options
swscale: fix non-bitexact yuv2yuv[X2]() MMX/MMX2 functions.
configure: report yasm/nasm presence properly
tcp: make connect() timeout properly
rawdec: factor video demuxer definitions into a macro.
rtspdec: add initial_pause private option.
lavf: deprecate AVFormatParameters.width/height.
tty: add video_size private option.
rawdec: add video_size private option.
x11grab: add video_size private option.
x11grab: factorize returning error codes.
...
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavdevice/x11grab.c')
-rw-r--r-- | libavdevice/x11grab.c | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c index a41e11ab57..58a8ae5571 100644 --- a/libavdevice/x11grab.c +++ b/libavdevice/x11grab.c @@ -36,6 +36,9 @@ */ #include "config.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" #include <time.h> #include <X11/X.h> #include <X11/Xlib.h> @@ -52,10 +55,12 @@ */ struct x11_grab { + const AVClass *class; /**< Class for private options. */ int frame_size; /**< Size in bytes of a grabbed frame */ AVRational time_base; /**< Time base */ int64_t time_frame; /**< Current time */ + char *video_size; /**< String describing video size, set by a private option. */ int height; /**< Height of the grab frame */ int width; /**< Width of the grab frame */ int x_off; /**< Horizontal top-left corner coordinate */ @@ -91,6 +96,7 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) int y_off = 0; int use_shm; char *dpyname, *offset; + int ret = 0; dpyname = av_strdup(s1->filename); offset = strchr(dpyname, '+'); @@ -100,23 +106,37 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) *offset= 0; } - av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", s1->filename, dpyname, x_off, y_off, ap->width, ap->height); + if ((ret = av_parse_video_size(&x11grab->width, &x11grab->height, x11grab->video_size)) < 0) { + av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); + goto out; + } +#if FF_API_FORMAT_PARAMETERS + if (ap->width > 0) + x11grab->width = ap->width; + if (ap->height > 0) + x11grab->height = ap->height; +#endif + av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", + s1->filename, dpyname, x_off, y_off, x11grab->width, x11grab->height); dpy = XOpenDisplay(dpyname); av_freep(&dpyname); if(!dpy) { av_log(s1, AV_LOG_ERROR, "Could not open X display.\n"); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto out; } - if (ap->width <= 0 || ap->height <= 0 || ap->time_base.den <= 0) { + if (ap->time_base.den <= 0) { av_log(s1, AV_LOG_ERROR, "AVParameters don't have video size and/or rate. Use -s and -r.\n"); - return AVERROR(EIO); + ret = AVERROR(EINVAL); + goto out; } st = av_new_stream(s1, 0); if (!st) { - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto out; } av_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ @@ -131,13 +151,14 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) ZPixmap, NULL, &x11grab->shminfo, - ap->width, ap->height); + x11grab->width, x11grab->height); x11grab->shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); if (x11grab->shminfo.shmid == -1) { av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n"); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto out; } x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0); x11grab->shminfo.readOnly = False; @@ -145,12 +166,13 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) if (!XShmAttach(dpy, &x11grab->shminfo)) { av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n"); /* needs some better error subroutine :) */ - return AVERROR(EIO); + ret = AVERROR(EIO); + goto out; } } else { image = XGetImage(dpy, RootWindow(dpy, DefaultScreen(dpy)), x_off,y_off, - ap->width,ap->height, + x11grab->width, x11grab->height, AllPlanes, ZPixmap); } @@ -173,7 +195,8 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) } else { av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto out; } break; case 24: @@ -188,7 +211,8 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) } else { av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto out; } break; case 32: @@ -211,13 +235,12 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) break; default: av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel); - return -1; + ret = AVERROR(EINVAL); + goto out; } - x11grab->frame_size = ap->width * ap->height * image->bits_per_pixel/8; + x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8; x11grab->dpy = dpy; - x11grab->width = ap->width; - x11grab->height = ap->height; x11grab->time_base = ap->time_base; x11grab->time_frame = av_gettime() / av_q2d(ap->time_base); x11grab->x_off = x_off; @@ -227,13 +250,15 @@ x11grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->width = ap->width; - st->codec->height = ap->height; + st->codec->width = x11grab->width; + st->codec->height = x11grab->height; st->codec->pix_fmt = input_pixfmt; st->codec->time_base = ap->time_base; st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(ap->time_base) * 8; - return 0; +out: + av_freep(&x11grab->video_size); + return ret; } /** @@ -436,6 +461,20 @@ x11grab_read_close(AVFormatContext *s1) return 0; } +#define OFFSET(x) offsetof(struct x11_grab, x) +#define DEC AV_OPT_FLAG_DECODING_PARAM +static const AVOption options[] = { + { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), FF_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC }, + { NULL }, +}; + +static const AVClass x11_class = { + .class_name = "X11grab indev", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + /** x11 grabber device demuxer declaration */ AVInputFormat ff_x11_grab_device_demuxer = { @@ -447,4 +486,5 @@ AVInputFormat ff_x11_grab_device_demuxer = x11grab_read_packet, x11grab_read_close, .flags = AVFMT_NOFILE, + .priv_class = &x11_class, }; |