Я пытаюсь кодировать растровое изображение с помощью TurboJpegEncoder. Это работает для некоторых разрешений, но для некоторых это не работает. И это дает «Попытку чтения или записи защищенной памяти. Это часто указывает на то, что другая память повреждена».
Например, это не работает, если разрешение 1618x888, но работает, если разрешение 1620 x888
Я пробовал разные значения для некоторых, это работает, а другие нет 'т работа. Как я понимаю, значение должно делиться на 4. Но для некоторых значений, даже если ширина и высота делится на 4. Это не работает.
Как мне найти правильные значения для работы? Как это рассчитывается? Я хочу иметь возможность сделать скриншот любого разрешения и транслировать его через webrtc. (все работает, если я даю разрешение как 1620x888)
это то, как я устанавливаю свои значения и буфер
public static int screenWidth = 1618;
public static int screenHeight = 888;
GCHandle bufHandle;
readonly byte[] imgBuf = new byte[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;
}