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".

Reply via email to