Open emako opened 4 months ago
I haven't touched that code in 5 years.
If COMPATBGR32 was removed, that's the format expected by the display image buffer. It looks like it's not getting data in the expected format. It would require some code rewrite.
Could you fix this error?
I honestly don't have time to work on this for now.
But if someone fixes it, I'll gladly merge the PR.
Find the sample code from preview_dialog.cpp in VapourSynth-Editor
QPixmap PreviewDialog::pixmapFromRGB(
const VSFrame * a_cpFrame)
{
if((!m_cpVSAPI) || (!a_cpFrame))
return QPixmap();
const VSVideoFormat * cpFormat = m_cpVSAPI->getVideoFrameFormat(a_cpFrame);
Q_ASSERT(cpFormat);
int wwidth = m_cpVSAPI->getFrameWidth(a_cpFrame, 0);
if((cpFormat->colorFamily != cfGray)
|| (cpFormat->bitsPerSample != 8)
|| (wwidth % 4))
{
QString errorString = tr("Error forming pixmap from frame. "
"Expected format Gray8 with width divisible by 4. ");
emit signalWriteLogMessage(mtCritical, errorString);
return QPixmap();
}
const VSMap *props = m_cpVSAPI->getFramePropertiesRO(a_cpFrame);
enum p2p_packing packing_fmt = static_cast<p2p_packing>(
m_cpVSAPI->mapGetInt(props, "PackingFormat", 0, nullptr));
bool is_10_bits;
if (packing_fmt == p2p_rgb30)
{
is_10_bits = true;
}
else if (packing_fmt == p2p_argb32)
{
is_10_bits = false;
}
else
{
QString errorString = tr("Error forming pixmap from frame. "
"Expected frame being packed from RGB24 or RGB30.");
emit signalWriteLogMessage(mtCritical, errorString);
return QPixmap();
}
int width = wwidth / 4;
int height = m_cpVSAPI->getFrameHeight(a_cpFrame, 0);
int stride = m_cpVSAPI->getStride(a_cpFrame, 0);
const uint8_t * pData = m_cpVSAPI->getReadPtr(a_cpFrame, 0);
QImage frameImage(reinterpret_cast<const uchar *>(pData),
width, height, stride, is_10_bits ?
QImage::Format_RGB30 : QImage::Format_ARGB32);
QPixmap framePixmap = QPixmap::fromImage(frameImage, Qt::NoFormatConversion);
return framePixmap;
}
old vsedit code from https://github.com/YomikoR/VapourSynth-Editor/blob/r19/vsedit/src/preview/preview_dialog.cpp
QPixmap PreviewDialog::pixmapFromCompatBGR32(
const VSFrameRef * a_cpFrameRef)
{
if((!m_cpVSAPI) || (!a_cpFrameRef))
return QPixmap();
const VSFormat * cpFormat = m_cpVSAPI->getFrameFormat(a_cpFrameRef);
Q_ASSERT(cpFormat);
if(cpFormat->id != pfCompatBGR32)
{
QString errorString = trUtf8("Error forming pixmap from frame. "
"Expected format CompatBGR32. Instead got \'%1\'.")
.arg(cpFormat->name);
emit signalWriteLogMessage(mtCritical, errorString);
return QPixmap();
}
int width = m_cpVSAPI->getFrameWidth(a_cpFrameRef, 0);
int height = m_cpVSAPI->getFrameHeight(a_cpFrameRef, 0);
const void * pData = m_cpVSAPI->getReadPtr(a_cpFrameRef, 0);
int stride = m_cpVSAPI->getStride(a_cpFrameRef, 0);
QImage frameImage((const uchar *)pData, width, height,
stride, QImage::Format_RGB32);
QImage flippedImage = frameImage.mirrored();
QPixmap framePixmap = QPixmap::fromImage(flippedImage);
return framePixmap;
}
This is C++ code. Converting it to .NET is not that simple. Won't be using the same libraries to do the pixel conversion work. I don't know if there's a simple solution other than the defunct 'compat' mode.
Also I wrote this for Windows-only and I'm now on Linux. Modernizing it would require considerable work.
I haven't followed other developments in the community. What is this VS viewer doing better than other alternatives? I wonder how many people have been using it.
The latest vsedit use #include <vapoursynth/VapourSynth4.h>
instead of #include <vapoursynth/VapourSynth.h>
.
The v4 api, added the audio APIs to struct VSAPI
, such as https://github.com/vapoursynth/vapoursynth/blob/master/include/VapourSynth4.h
Maybe I can't migrate the c++ code from the latest version of vsedit.
https://github.com/vapoursynth/vapoursynth/blob/master/sdk/vsscript_example.c
SDK example
for (int n = 0; n < vi->numFrames; n++) {
const VSFrame *frame = vsapi->getFrame(n, node, errMsg, sizeof(errMsg));
if (!frame) { // Check if an error happened when getting the frame
error = 1;
break;
}
// Loop over every row of every plane write to the file
for (int p = 0; p < vi->format.numPlanes; p++) {
ptrdiff_t stride = vsapi->getStride(frame, p);
const uint8_t *readPtr = vsapi->getReadPtr(frame, p);
int rowSize = vsapi->getFrameWidth(frame, p) * vi->format.bytesPerSample;
int height = vsapi->getFrameHeight(frame, p);
for (int y = 0; y < height; y++) {
// You should probably handle any fwrite errors here as well
fwrite(readPtr, rowSize, 1, outFile);
readPtr += stride;
}
}
vsapi->freeFrame(frame);
}
and then
VsVideoInfo vi = e.Frame.GetVideoInfo();
WriteableBitmap Bmp = new WriteableBitmap(vi.Width, vi.Height, 96, 96, PixelFormats.Rgb24, null);
nint writePtr = Bmp.BackBuffer;
Bmp.Lock();
for (int p = 0; p < vi.Format.NumPlanes; p++)
{
VsPlane plane = e.Frame.GetPlane(p);
int stride = plane.Stride;
nint readPtr = plane.Ptr;
int rowSize = plane.GetFrameWidth(p) * vi.Format.BytesPerSample;
int height = plane.GetFrameHeight(p);
for (int y = 0; y < height; y++)
{
memcpy(writePtr, readPtr, rowSize);
readPtr = IntPtr.Add(readPtr, stride);
writePtr = IntPtr.Add(writePtr, stride);
}
}
Bmp.AddDirtyRect(new Int32Rect(0, 0, vi.Width, vi.Height));
Bmp.Unlock();
Preview
btw came upon this code that is similar to what's needed to convert frame data.
I don't whether doing it manually like that is the only option; the issue is that we then have to support every input format. Whereas with the COMPAT type, VapourSynth handles all formats automatically.
Also doing it manually doesn't have assembly optimization and will be considerably slower than properly-optimized frame conversion code.
Possibly SixLabors.ImageSharp would allow doing the frame conversions we need
https://docs.sixlabors.com/articles/imagesharp/gettingstarted.html
Indeed once you have it in an Image object, can convert it to the desired format.
image.CloneAs<Rgba32>();
I change some codes like following:
https://www.vapoursynth.com/2021/09/r55-audio-support-and-improved-performance/ Because COMPATBGR32 was removed so that I set the COMPATBGR32.vpy file to empty, and use vs.RGB24 to instead .
example vpy script here:
but vapoursynthviewer.net rendering incorrectly:
vsedit is rendering good:
Do you have any idea what's going on?