Celestia 1.7.0 Development Thread

The place to discuss creating, porting and modifying Celestia's source code.
john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1201by john71 » 19.01.2022, 09:21

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.

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1202by cartrite » 19.01.2022, 09:30

I think celestia.dll is what is getting the original to work because the fix is in that library.

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.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1203by john71 » 19.01.2022, 09:34

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.

I searched for this problem and there are a lot of words for it like flipped, mirrored, reversed video.

"Mirroring" is a common effect, so ffmpeg may be able to correct this with a built in command.

Maybe mirroring=reversing. I hope it is not a temporal reverse.

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1204by cartrite » 19.01.2022, 09:52

I don't think the videos were reversed. When I recorded earth, I increased the rotation by increasing time to 1000x. The rotation was still going forward but it was upside down. With uncompressed files, the avi format reads the file from the bottom up. So the height in the header needs to be negative to get it to read from the top down. But the compressed files are read from the top down. So I am not sure why these files are upside down.

The Linux and Mac versions use FFMpeg. The windows version can build the ffmpegcapture.cpp but FFMpeg is turned off in the code. I tried to turn it on but kept getting build errors. So I tried to get avicapture to work but it only works for uncompressed files.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1205by john71 » 19.01.2022, 10:03

cartrite wrote:So I tried to get avicapture to work but it only works for uncompressed files.

I don't get it. SOMETHING is working, because we can use the video recording function with every codec and there are excellent (mirrored) videos.

Which part of the software makes the video file?

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1206by cartrite » 19.01.2022, 10:09

I did not include the fix I did because it breaks compressed recordings. When I record a video that is uncompressed, the file is recorded correctly. But when I try to record a compressed video, I get an error that tells me the the video can not be recorded. It fails. So I did not include that fix in the installer.

As for your question, Linux and Mac operating systems are using FFMpeg to capture videos. Windows operating systems are using AVI to record videos.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1207by john71 » 19.01.2022, 10:16

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!

This "mirroring bug" must be a minor dysfunction in the current code.

Also this problem seems to be a video data communication problem, not a video recording problem.

The recording function is working just fine.

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1208by cartrite » 19.01.2022, 10:32

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!
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.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1209by john71 » 19.01.2022, 10:40

That's OK, but they should just "flip" the video data in the code, right?

That is not very complicated.

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1210by cartrite » 19.01.2022, 10:58

I don't think it is that simple or they would have already done it. Computer code sometimes does what is not expected. That is a bug.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1211by john71 » 19.01.2022, 11:16

cartrite wrote:I don't think it is that simple or they would have already done it.

It must be some kind of matrix transformation, like the Householder Matrix.

Janus
Posts: 537
Joined: 13.08.2016
With us: 8 years 3 months

Post #1212by Janus » 22.01.2022, 04:36

Concerning video "flip" needing doing.

Thought it would be something I could do with compare and contrast and a few compiles.
Just got done trying to compile the current commit, and what a mess it is now.
Have to install a compiler, to build another compiler, to build a library, wow, no wonder no wants to build for windows directly anymore.
After discovering that my Win7 system to "old" for meson/ninja and requires python which I don't keep installed.
I put it away, likely done with this project now since I am never allowing W10 on my network, it leaks WAY! to much data.

Anyway, not wanting to rant, just disgusted, I like celestia, a lot.
I will miss it if I can't find a way around the above.

I would start with gl::MESA_pack_invert and its use in the renderer::captureframe function of render.cpp.
The built in windows avi subsystem directly handles the pixels from glreadpixels natively, no problem.
If you are using ffmpeg, it can be told what to expect, so there is no need to use the above mesa/opengl function.
If linux needs or requires it, didn't check the theora code in the linux section, the just check for !WIN32 and invert, a compile time check.


Janus.

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1213by john71 » 22.01.2022, 07:10

Janus wrote:Concerning video "flip" needing doing.

I don't understand this.

1.) there has to be some kind of video data transfer before the video recording function: screen data inside Celestia -> recording this data

2.) there has to be some kind of source for the video recording, Celestia must transfer the "source video data" to the "capture code"

3.) the video recorder is working PERFECTLY: why should we change it?

4.) so WHY is it impossible to flip the video data BEFORE it arrives to the video capture code?

5.) how can it be the fault of Windows 10, when in 1.6.2.2 everything is working just fine?

Janus
Posts: 537
Joined: 13.08.2016
With us: 8 years 3 months

Post #1214by Janus » 22.01.2022, 08:13

@John71

The fault isn't W10.
As much as I would like to blame it, and its many many faults, it is not the problem here.

The problem is likely a byproduct of going between platforms.
render::captureframe is new, and has more features/options.

I am unsure of how video capture works in linux, which is where the main development focus seems to be currently.
However, it is possible that there is a reason to flip the pixels before sending them to the video stream compressor.
Right now I simply don't remember everything, my attention has been focused on work the last two years, and I am further behind now than I a was then.
I do however, remember in my reading that there are some differences between how win and linux systems handle video at the codec level.

From 1.6.1 src/celestia/avicapture.cpp

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;
   }


From commit:6341 src/celestia/avicapture.cpp

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;
   }


As you can see, there is little difference between them.
Mainly the introduction of a new function in the renderer class.

Commit:6341 src/celengine/render.cpp

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;
   }


The key here is MESA_pack_invert, which is a feature/toggle in the opengl section.
It is also used in render::init in the same file.

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;
   }


I could be missing something, but this looks like where the issue is.
Exactly what the issue is however, I am not certain.

I had intended to solve this, but am unable to.
I cannot compile libepoxy, an opengl helper, because the meson compiler for it doesn't work with win7.
I could compile the compiler however, except that ninja also doesn't work for me, and they require python which I don't keep on my system.
Frustrating, since I have acquired VS17 & VS19 both, yet am still unable to do what I want.

The current setup requires a system configured in a certain way, which I do not use.
Many assumptions are made, which are a mismatch for me.
I will look at bootstrapping stuff later when I have time to play, which I currently do not.
The last two years have been ridiculous, and look to stay that way.

I wish you the best of luck getting this fixed.


Janus.

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1215by john71 » 22.01.2022, 10:03

Use MESA_pack_invert to avoid read_pixels flip

cogl_read_pixels returns image data in a top-down memory order, but
because OpenGL normally returns pixel data in a bottom-up order we
have to flip the data before returning it to the user. If the OpenGL
driver supports the GL_MESA_pack_invert extension though we can ask the
driver to return the data in a top-down order in the first place.

https://mail.gnome.org/archives/commits-list/2011-July/msg06114.html

https://hackage.haskell.org/package/OpenGLRaw-2.6 ... penGL-Raw-MESA-PackInvert.html

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1216by cartrite » 22.01.2022, 10:58

Here is a quote from OpenGL-Registry/extensions/MESA/MESA_pack_invert.txt
https://github.com/KhronosGroup/OpenGL-Registry/blob/main/extensions/MESA/MESA_pack_invert.txt
"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
"

So something like this may work.

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

Linux and MAC have this set to true. FFMpeg probably knows how to deal with this. AVI doesn't.
Got to go to work now. I'll try this tonight.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

Topic author
onetwothree
Site Admin
Posts: 706
Joined: 22.09.2018
With us: 6 years 1 month

Post #1217by onetwothree » 22.01.2022, 17:07

GL_MESA_pack_invert is not supported on windows.

Added after 4 minutes 44 seconds:
if for some strange reason AVIStreamWrite works with flipped video we can simply pass an additional parameter to Renderer::captureFrame. And just in case add the proposed change to Rendere::init.

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1218by cartrite » 22.01.2022, 18:00

Last week I was reading about the avi format. It said that uncompresed files are store bottom up and compressed files are stored top down,. When I changed the avi header for height to a negative number, the uncompressed file was not inverted. But the compressed files would never capture. But all files are saved inverted compressed or not with no changes.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

john71
Posts: 1009
Joined: 10.08.2016
With us: 8 years 3 months

Post #1219by john71 » 22.01.2022, 19:07

Maybe this is relevant:

// Create a temp buffer that we'll use for flipping the dib since it needs to
// be upside down for windows.

m_pbmFlip = CreateDibBitmap(NULL, cx, cy);
if (m_pbmFlip == NULL)
return false;

https://cpp.hotexamples.com/examples/-/-/AVIFileI ... ileinit-function-examples.html

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Post #1220by cartrite » 22.01.2022, 19:31

Maybe the best way to do this is implement FFMpeg in Windows. This was the first thing I tried but gave up.
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4


Return to “Development”