Невозможно кодировать изображения с разным разрешением с помощью TurboJpegEncoder. Хотя я могу делать определенные решения

Я пытаюсь кодировать растровое изображение с помощью TurboJpegEncoder. Это работает для некоторых разрешений, но для некоторых не работает. И выдает сообщение "Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена".

Например, он не работает, если разрешение 1618x888, но работает, если разрешение составляет 1620 x888.

Я пробовал разные значения, одни работают, а другие не работают. Насколько я понимаю, значение должно делиться на 4. Но для некоторых значений, даже если ширина и высота делятся на 4, это не работает.

Как я могу найти правильные значения для работы? Как это вычисляется? Я хочу иметь возможность делать снимки экрана в любом разрешении и транслировать их через webrtc. (все работает, если я даю разрешение 1620x888)

вот как я устанавливаю свои значения и буфер

    public static int screenWidth = 1618;
    public static int screenHeight = 888;
    GCHandle bufHandle;

    readonly byte[] imgBuf = newbyte[screenWidth * 3 * screenHeight];

вот как я рассчитываю шаг

            int bitsPerPixel = ((int)PixelFormat.Format24bppRgb & 0xff00) >> 8;
            int bytesPerPixel = (bitsPerPixel + 7) / 8;
            int stride = 4 * ((screenWidth * bytesPerPixel + 3) / 4);

вот как я готовлю хендлера

                bufHandle = GCHandle.Alloc(imgBuf, GCHandleType.Pinned);
                imgBufPtr = bufHandle.AddrOfPinnedObject();
                img = new Bitmap(screenWidth, screenHeight, stride, PixelFormat.Format24bppRgb, imgBufPtr);

после этого я копирую изображение в буфер

                     g = Graphics.FromImage(img);

наконец, я пытаюсь закодировать это

                    if (session == null) return;
                    var yuv = session.WebRtc.VideoCapturerI420Buffer();
                    if (yuv != null)
                    {

                        encoderRemote.EncodeI420((byte*)imgBufPtr.ToPointer(), screenWidth, screenHeight, (int)TJPF.TJPF_BGR, 0, true, yuv);

                    }

функция собственного кодирования похожа на следующую

int TurboJpegEncoder::EncodeI420(Byte * rgbBuf, Int32 w, Int32 h, Int32 pxFormat, Int64 yuvSize, Boolean fast, Byte * yuv)
    {
        int pad = 4;

        int width = w;
        int height = h;
        int pitch = TJPAD(tjPixelSize[pxFormat] * width);

        if (yuvSize > 0)
        {
            int yuvSizeCheck = tjBufSizeYUV2(width, pad, height, TJSAMP_420);
            if (yuvSizeCheck != yuvSize)
            {
                Debug::WriteLine(String::Format("tjBufSizeYUV2, yuvSizeCheck[{0}] != {1}", yuvSizeCheck, yuvSize));
                return -1;
            }
        }



            int r = tjEncodeYUV3(jpegc, rgbBuf, width, pitch, height, pxFormat, yuv, pad, TJSAMP_420, fast ? TJFLAG_FASTDCT : TJFLAG_ACCURATEDCT);
            if (r != 0)
            {
                Debug::WriteLine(String::Format("tjEncodeYUV3, LastJpegError: {0}", LastJpegError));
                return r;
            }

        return 0;
    }

0 ответов

Другие вопросы по тегам