cartrite wrote:I'm not sure what you mean by that.
There are 3 exe files in the Celestia main folder: 2 new ones (-qt and -win) and the original celestia.exe.
cartrite wrote:I'm also not sure what you mean by reverse video. I thought it was only recording upside down. You seem to be saying it is recording upside down and in reverse? I never recorded a video long enough to notice.
cartrite wrote:So I did not include that fix in the installer.
This is not up to me. The Development Team has decided this. Because they don't have a developer for Windows. I just don;t know enough to fill that role completely. All I can do is try to help in the background. AVI libraries are part of the Windows operating system and those libraries make recording possible on machines that use Windows.john71 wrote:cartrite wrote:So I did not include that fix in the installer.
I mean how is it possible to capture mirrored and compressed videos without ffmpeg?
Why do you want to use avicapture? Something is capturing compressed videos right now!
Janus wrote:Concerning video "flip" needing doing.
Code: Select all
bool AVICapture::captureFrame()
{
if (!capturing)
return false;
// Get the dimensions of the current viewport
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
int x = viewport[0] + (viewport[2] - width) / 2;
int y = viewport[1] + (viewport[3] - height) / 2;
glReadPixels(x, y, width, height,
GL_BGR_EXT, GL_UNSIGNED_BYTE,
image);
int rowBytes = (width * 3 + 3) & ~0x3;
LONG samplesWritten = 0;
LONG bytesWritten = 0;
HRESULT hr = AVIStreamWrite(compAviStream,
frameCounter,
1,
image,
rowBytes * height,
AVIIF_KEYFRAME,
&samplesWritten,
&bytesWritten);
if (hr != AVIERR_OK)
{
DPRINTF(0, "AVIStreamWrite failed on frame %d\n", frameCounter);
return false;
}
// printf("Writing frame: %d %d => %d bytes\n",
// frameCounter, rowBytes * height, bytesWritten);
frameCounter++;
return true;
}
Code: Select all
bool AVICapture::captureFrame()
{
if (!capturing)
return false;
// Get the dimensions of the current viewport
int x, y, w, h;
renderer->getViewport(&x, &y, &w, &h);
x += (w - width) / 2;
y += (h - height) / 2;
renderer->captureFrame(x, y, width, height,
PixelFormat::BGR,
image);
int rowBytes = (width * 3 + 3) & ~0x3;
LONG samplesWritten = 0;
LONG bytesWritten = 0;
HRESULT hr = AVIStreamWrite(compAviStream,
frameCounter,
1,
image,
rowBytes * height,
AVIIF_KEYFRAME,
&samplesWritten,
&bytesWritten);
if (hr != AVIERR_OK)
{
GetLogger()->error("AVIStreamWrite failed on frame {}\n", frameCounter);
return false;
}
// fmt::printf("Writing frame: %d %d => %d bytes\n",
// frameCounter, rowBytes * height, bytesWritten);
frameCounter++;
return true;
}
Code: Select all
bool Renderer::captureFrame(int x, int y, int w, int h, PixelFormat format, unsigned char* buffer) const
{
glReadPixels(x, y, w, h, toGLFormat(format), GL_UNSIGNED_BYTE, (void*) buffer);
bool ok = glGetError() == GL_NO_ERROR;
if (!ok)
return false;
if (!gl::MESA_pack_invert)
{
int realWidth = w * formatWidth(format);
realWidth = (realWidth + 3) & ~0x3;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
uint8_t tempLine[realWidth]; // G++ supports VLA as an extension
#else
uint8_t *tempLine = static_cast<uint8_t*>(alloca(realWidth));
#endif
uint8_t *fb = buffer;
for (int i = 0, p = realWidth * (h - 1); i < p; i += realWidth, p -= realWidth)
{
memcpy(tempLine, &fb[i], realWidth);
memcpy(&fb[i], &fb[p], realWidth);
memcpy(&fb[p], tempLine, realWidth);
}
}
return ok;
}
Code: Select all
bool Renderer::init(int winWidth, int winHeight,
DetailOptions& _detailOptions)
{
detailOptions = _detailOptions;
// Initialize static meshes and textures common to all instances of Renderer
if (!commonDataInitialized)
{
g_lodSphere = new LODSphereMesh();
gaussianDiscTex = BuildGaussianDiscTexture(8);
gaussianGlareTex = BuildGaussianGlareTexture(9);
commonDataInitialized = true;
}
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
if (gl::MESA_pack_invert) glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
// LEQUAL rather than LESS required for multipass rendering
glDepthFunc(GL_LEQUAL);
resize(winWidth, winHeight);
return true;
}
"The parameter PACK_INVERT_MESA controls whether the image is packed
in bottom-to-top order (the default) or top-to-bottom order. Equation
3.8 is modified as follows:
... the first element of the Nth row is indicated by
p + Nk, if PACK_INVERT_MESA is false
p + k * (H - 1) - Nk, if PACK_INVERT_MESA is true, where H is the
image height
"
Code: Select all
#ifdef _WIN32
if (gl::MESA_pack_invert) glPixelStorei(GL_PACK_INVERT_MESA, GL_FALSE);
else
if (gl::MESA_pack_invert) glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
#endif