Невозможно кодировать изображения с разным разрешением с помощью 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;
}