In the spirit of "patches welcome" I've tried to fix this on my own. Patch
attached.
Currently I'm hitting this error:
Error while decoding stream #0:0: Invalid argument
[rawvideo @ 0x55b961f49180] Invalid buffer size, packet size 3145728 <
expected frame_size 4718592
I'd appreciate any help!
Tom
On Fri, Apr 29, 2022 at 12:47:06PM -0700, amindfv--- via ffmpeg-user wrote:
> With the latest git version on Debian, I try and screen record.
>
> My system is set up for 10-bit color, which I assume is the "mapping pixmap
> format" issue.
>
> Is anyone working on - or willing to work on - adding support for this pixel
> format? It would be very appreciated!
>
> Thanks,
> Tom
>
> $ ./ffmpeg -video_size 1024x768 -framerate 25 -f x11grab -i :0.0+100,200
> output.mp4
> ffmpeg version N-106747-g3415028d13 Copyright (c) 2000-2022 the FFmpeg
> developers
> built with gcc 10 (Debian 10.2.1-6)
> configuration:
> libavutil 57. 24.101 / 57. 24.101
> libavcodec 59. 27.100 / 59. 27.100
> libavformat 59. 23.100 / 59. 23.100
> libavdevice 59. 6.100 / 59. 6.100
> libavfilter 8. 37.100 / 8. 37.100
> libswscale 6. 6.100 / 6. 6.100
> libswresample 4. 6.100 / 4. 6.100
> [x11grab @ 0x5574a7e12140] Mapping this pixmap format is not implemented.
> Update your FFmpeg version to the newest one from Git. If the problem still
> occurs, it means that your file has a feature which has not been implemented.
> :0.0+100,200: Not yet implemented in FFmpeg, patches welcome
> _______________________________________________
> ffmpeg-user mailing list
> [email protected]
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> To unsubscribe, visit link above, or email
> [email protected] with subject "unsubscribe".
diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c
index 64a68ba497..5663d30fe7 100644
--- a/libavdevice/xcbgrab.c
+++ b/libavdevice/xcbgrab.c
@@ -65,6 +65,7 @@ typedef struct XCBGrabContext {
int width, height;
int frame_size;
int bpp;
+ int bpcc; // bits per color component
int draw_mouse;
int follow_mouse;
@@ -337,7 +338,7 @@ static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt,
XCBGrabContext *gr = s->priv_data;
uint32_t *cursor;
uint8_t *image = pkt->data;
- int stride = gr->bpp / 8;
+ int stride = gr->bpp / gr->bpcc; // This right? May be 32 bits width for 30 bits of information
xcb_xfixes_get_cursor_image_cookie_t cc;
xcb_xfixes_get_cursor_image_reply_t *ci;
int cx, cy, x, y, w, h, c_off, i_off;
@@ -372,10 +373,10 @@ static void xcbgrab_draw_mouse(AVFormatContext *s, AVPacket *pkt,
for (x = 0; x < w; x++, cursor++, image += stride) {
int r, g, b, a;
- r = *cursor & 0xff;
- g = (*cursor >> 8) & 0xff;
- b = (*cursor >> 16) & 0xff;
- a = (*cursor >> 24) & 0xff;
+ r = *cursor & 0xff;
+ g = (*cursor >> (gr->bpcc)) & 0xff;
+ b = (*cursor >> (2*(gr->bpcc))) & 0xff;
+ a = (*cursor >> (3*(gr->bpcc))) & 0xff;
if (!a)
continue;
@@ -515,7 +516,7 @@ static xcb_screen_t *get_screen(const xcb_setup_t *setup, int screen_num)
}
static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth,
- int *pix_fmt, int *bpp)
+ int *pix_fmt, int *bpp, int *bpcc)
{
XCBGrabContext *c = s->priv_data;
const xcb_setup_t *setup = xcb_get_setup(c->conn);
@@ -528,31 +529,49 @@ static int pixfmt_from_pixmap_format(AVFormatContext *s, int depth,
if (fmt->depth == depth) {
switch (depth) {
case 32:
- if (fmt->bits_per_pixel == 32)
+ if (fmt->bits_per_pixel == 32) {
*pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
AV_PIX_FMT_BGR0 : AV_PIX_FMT_0RGB;
+ *bpcc = 8;
+ }
+ break;
+ case 30:
+ if (fmt->bits_per_pixel == 32) {
+ *pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
+ AV_PIX_FMT_YUV444P10LE : AV_PIX_FMT_YUV444P10BE;
+ *bpcc = 10;
+ }
break;
case 24:
- if (fmt->bits_per_pixel == 32)
+ if (fmt->bits_per_pixel == 32) {
*pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
AV_PIX_FMT_BGR0 : AV_PIX_FMT_0RGB;
- else if (fmt->bits_per_pixel == 24)
+ *bpcc = 8;
+ } else if (fmt->bits_per_pixel == 24) {
*pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24;
+ *bpcc = 8;
+ }
break;
case 16:
- if (fmt->bits_per_pixel == 16)
+ if (fmt->bits_per_pixel == 16) {
*pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
AV_PIX_FMT_RGB565LE : AV_PIX_FMT_RGB565BE;
+ *bpcc = 8;
+ }
break;
case 15:
- if (fmt->bits_per_pixel == 16)
+ if (fmt->bits_per_pixel == 16) {
*pix_fmt = setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST ?
AV_PIX_FMT_RGB555LE : AV_PIX_FMT_RGB555BE;
+ *bpcc = 8;
+ }
break;
case 8:
- if (fmt->bits_per_pixel == 8)
+ if (fmt->bits_per_pixel == 8) {
*pix_fmt = AV_PIX_FMT_RGB8;
+ *bpcc = 8;
+ }
break;
}
}
@@ -616,17 +635,17 @@ static int create_stream(AVFormatContext *s)
c->frame_duration = av_rescale_q(1, c->time_base, AV_TIME_BASE_Q);
c->time_frame = av_gettime_relative();
- ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codecpar->format, &c->bpp);
+ ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codecpar->format, &c->bpp, &c->bpcc);
free(geo);
if (ret < 0)
return ret;
frame_size_bits = (int64_t)c->width * c->height * c->bpp;
- if (frame_size_bits / 8 + AV_INPUT_BUFFER_PADDING_SIZE > INT_MAX) {
+ if (frame_size_bits / c->bpcc + AV_INPUT_BUFFER_PADDING_SIZE > INT_MAX) {
av_log(s, AV_LOG_ERROR, "Captured area is too large\n");
return AVERROR_PATCHWELCOME;
}
- c->frame_size = frame_size_bits / 8;
+ c->frame_size = frame_size_bits / c->bpcc;
#if CONFIG_LIBXCB_SHM
c->shm_pool = av_buffer_pool_init2(c->frame_size + AV_INPUT_BUFFER_PADDING_SIZE,
_______________________________________________
ffmpeg-user mailing list
[email protected]
https://ffmpeg.org/mailman/listinfo/ffmpeg-user
To unsubscribe, visit link above, or email
[email protected] with subject "unsubscribe".