HOWTO: Making MPEG Movies with Geomview

This document is being posted on the internet mostly so that I don't lose it. Hopefully, someone else will find it useful, too.

To make a movie using Geomview, there are a couple of steps you need to go through. First, you need to generate the frames, capture the frames, and then stitch the frames together into a movie. Here, we'll assume that you've already generated the mesh/object files needed to specify the frames you want.

Capturing the Frames

Although you can use the Animator plugin to generate movies (you can specify an arbitrary GCL (geomview command language) command to execute after each frame; using the snapshot command will dump frames), you can't really use Animator to generate long movies, because Animator has to load all of the data files into RAM. This limits movie lengths pretty severely.

A different approach is to convince geomview to load a frame, snapshot it, and then delete it. This can be accomplished by writing a GCL script that does just that.

The first trick is that (as far as I can tell) you have to actually have the window on your screen, visible -- geomview does some sort of software window capture, which means that if you leave this running on a virtual desktop that isn't visible, you'll get garbage.

The GCL file you want should have three lines for each frame in your movie, like this:
(load filename geometry)
(snapshot c0 outputfilename)
(delete filename)
and save it to a regular text file (call it script.txt). The first few lines of mine looked like this:
(load MCAR-000050 geometry)
(snapshot c0 /tmp/movie3/MCAR-000050.rgb)
(delete MCAR-000050)
(load MCAR-000051 geometry)
(snapshot c0 /tmp/movie3/MCAR-000051.rgb)
(delete MCAR-000051)
(load MCAR-000052 geometry)
(snapshot c0 /tmp/movie3/MCAR-000052.rgb)
(delete MCAR-000052)
...
Obviously, in this example, "script.txt" is in the same directory as all of the data files (although that doesn't need to be the case). It will dump all of the frames to "/tmp/movie3"; make sure that this directory exists before you start.

Next, load and execute the file containing all of the commands by going to the "Inspect" menu, and selecting "Commands", and typing
(load scriptname commands)
It helps if you start geomview from the directory that contains the script and the data files. This will load, snapshot, and dump all of the data files to a directory (in the example, "/tmp/movie3") in .rgb format. You can actually dump in different formats; see the geomview documentation for details.

Each frame is snapshotted using the current orientation of the default camera (and all of the attendant settings -- shading mode, perspective mode, whether or not bounding boxes and edges are shown, etc.) It helps if you load up a datafile, position the camera where you want it, set all of the other parameters how you want them, and then delete the object and run the script.

For the purposes of making a movie, it will help A LOT if you snapshot all of the datafiles at the final resolution of the movie. I wanted to make 400x400 movies, so I edited my ~/.geomview file to include the following lines:
(echo c0)
(window c0 {position 200 599 100 499})
(backcolor c0 1 1 1)
The echo command is useless; for some reason, geomview executes all but one of the commands in my .geomview file, so this is just a little bit of padding.

The window commands tells geomview to position and size the c0 camera window. Here, the width and height are set to be 400x400; this is an easy and precise way to do it. The backcolor command sets the background color to be all white.

By the way, MPEG videos require resolutions that are multiples of 8.

Encoding all of the frames
Once all of the snapshots are generated, I used transcode to generate the actual mpeg movie. Unfortunately, the rgb format dumped by geomview is a little bit different than the rgb format used by transcode. Specifically, transcode expects NO header information WHATSOEVER. So, I wrote a little perl script that just deleted the three lines of header, and re-wrote out the file. Easy.

This was really only necessary because I didn't build transcode with the imagemagick library support; if I had, transcode would have supported jpeg images natively, and I could have dumped from geomview in jpeg, and then imported directly into transcode. Your mileage may vary.

Once all of the files have been cleaned, you need a text list of all the frames (in order) that you want as part of your video. You should just have one filename per line; an easy way to do it is this:
ls -1 *.rgb > list.txt
The command line I used for transcode was
transcode -i list.txt -x rawlist,null -g 400x400 -y mpeg,null -w 8000 \
-f 5 -H 0 --import_asr 1 --export_asr 1 -o movie4.mpeg
Here is the interpretation thereof:
-i list.txt

  Specifies "list.txt" as the list of frames

-x rawlist,null

  "rawlist" is the video source, "null" is the audio source.  rawlist
  imports a list of raw [ie, rgb] frames as the video source.

-g 400x400

  400x400 is the resolution of the final video (or maybe it's the
  resolution of the input images.  Not sure.)

-y mpeg,null

  mpeg (version 1) is the video output format, null is the audio
  output format.

-w 8000

  Change the bitrate to be (almost) as high as possible

-f 5

  5 frames per second

-H 0

  don't autoprobe anything to attempt to automatically determine anything

--import_asr 1

  the import aspect ratio is 1:1

--export_asr 1

  the export aspect ratio is 1:1  (if you don't provide these two options,
  it will automatically export to a strange aspect ratio -- 4:3, maybe?)

-o movie4.mpeg

  call the resulting output file "movie4.mpeg".  Transcode will actually
  tack on a ".m1v" to the output filename.

You might wonder why I ended up using mpeg v1. It turns out that I also managed to get transcode to dump version 4 MPEG, but my ffmpeg library was busted (or something), so *no* other player ended up being able to read the resulting movies, except the machine that encoded it. Bummer.
 
The top of a fluffy cloud.