Note-to-self:

ffmpeg -i input.mp4 -x264opts keyint=15:min-keyint=15 -c:v libx264 -preset slow -crf 22 output.mp4

Links:

Tagged with:  

Here’s a video done by Ed Catmull (founder of Pixar) in 1972 while at the University of Utah. It’s purported to be the first digitally rendered film. It’s just amazing how far we’ve come since these early pioneering days.

The math that we take for granted for rendering 3D was being invented, real time, to create this video. (Ed’s credited for having working out that math to handle things like texture mapping, 3D anti-aliasing and z-buffering.)

The story behind the video and how it was found recently is pretty cool too. Props to Robby Ingebretsen for sharing this!


40 Year Old 3D Computer Graphics (Pixar, 1972) from Robby Ingebretsen on Vimeo.

Tagged with:  

Live555: Compiling with VS2008

On May 14, 2011, in Code Monkey, by Tom

Compiling Live555 Streaming Media with Visual Studio 2008 isn’t obvious. Using Cygwin or MinGW is just a pain and frankly unnecessary. There is no built-in support for VS solution files, because Windows support is a low priority for the Live555 community. This is evidenced by this forum response from Ross Finlayson:

>4. Is it possible to include a Visual Studio solution in the
>distrubution to make it more convenient for Windows developers to
>use live555?
>5. Is it possible for live555 to generate adequate makefiles for
>Windows systems with development environments newer than Visual
>Studio 2003?

I have no current plans to change this. (These days, fewer and fewer people seem to be using Windows for development of system software.)

Regardless, Live555 works fine on Windows and is actually quite easy to build. Simply do the following:

  1. Open the ‘win32config’ file and change the TOOLS32=... variable to your VS2008 install directory. For me, it’s TOOLS32=C:\Program Files\Microsoft Visual Studio 9.0\VC
  2. In ‘win32config’, modify the LINK_OPTS_0=... line from msvcirt.lib to msvcrt.lib. This fixes the link error:
    LINK : fatal error LNK1181: cannot open input file 'msvcirt.lib'
  3. Open the Visual Studio command prompt.
  4. From the ‘live’ source directory, run genWindowsMakefiles
  5. Now you’re ready to build. Simply run the following commands:
    cd liveMedia
    nmake /B -f liveMedia.mak
    cd ..\groupsock
    nmake /B -f groupsock.mak
    cd ..\UsageEnvironment
    nmake /B -f UsageEnvironment.mak
    cd ..\BasicUsageEnvironment
    nmake /B -f BasicUsageEnvironment.mak
    cd ..\testProgs
    nmake /B -f testProgs.mak
    cd ..\mediaServer
    nmake /B -f mediaServer.mak

That’s it. You should be good to go.

Tagged with:  

Rendering Video with GDI (Example)

On April 20, 2011, in Code Monkey, by Tom

In this post, I outline a basic GDI video window class. GDI is inefficient for rendering video, but it’s also very convinient when writing simple tools on Windows. I find myself doing it often enough that it makes sense to do a brain-dump here. This is only an outline, but it should get you over the biggest hurdles.

Outline

  1. Video Window Class Definition
  2. Creating and Destroying the Window
  3. The Window Thread
  4. The Message Pump
  5. Rendering a Video Frame

Things to note:

  • You will need a thread in your window class to “pump” window events.
  • GDI does NOT do any color conversion, so you will need to convert each frame into the same format as the display (always RGB, usually 24 or 32 bits).

Video Window Class Definition

class VideoWindow
{
public:
    ...
private:
    static DWORD _ThreadMain(void*);
    static LRESULT WINAPI _MsgProc(HWND, UINT, WPARAM, LPARAM);

    CRITICAL_SECTION _lok;
    HANDLE _thread;
    HWND _hWnd;
    HDC _hDC;
    HDC _hFrameDC;
    HFONT _hFont;
    int _bpp;   // bit depth
    volatile bool _exit;
    int _x, _y, _w, _h; // Window dimensions
    int _imgWidth, _imgHeight, _imgLength; // Frame dimensions
    unsigned char *_imgBits;
};

Creating and Destroying the Window

void VideoWindow::Create(int x, int y, int w, int h)
{
    EnterCriticalSection(&_lok);
    _x = x;
    _y = y;
    _w = w;
    _h = h;
    _hWnd = 0;
    _exit = false;
    _thread = CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)_ThreadMain,
        this, NULL, 0 );
    LeaveCriticalSection(&_lok);

    // Wait for window to be created. Cheap, but it works.
    while (!_hWnd) {
        ::Sleep(100);
    }
}
 

Continue reading »

Tagged with:  

ILM and GPU Programming

On October 7, 2010, in Code Monkey, Tech and Security, by Tom

Some artists from Industrial Light & Magic (ILM) gave the closing keynote at the GPU Technology Conference (GTC) in 2009… it’ s well worth watching by itself (watch here). At GTC 2010, they presented a video talking about how the GPU and CUDA are helping to render effects faster. It’s a short video with lots of cool effects.

ct>

Here’s a copy of the video if it is ever removed (13MB, 3gp).

Tagged with:  

FFMpeg provides many powerful features for processing audio and video. One cool thing it can do is resample an audio stream. This allows you to convert, say, a 44.1kHz audio stream down to 8kHz, or up to 48kHz. What’s more, FFMpeg can do the conversion to any arbitrary sample rate. This allows you to do cool things like smoothly changing the audio playback speed over time (see sample code below).

There are many pages describing how to resample audio using the ffmpeg command line application, but what about doing resampling in your own program? To do that, you need to use the avcodec library (libavcodec.so on Linux and avcodec.dll on Windows).

  1. Include avcodec.h
  2. Call avcodec_init() to initialize the FFMpeg library.
  3. Create a resampling context using av_resample_init() that describes how you want the resampling done.
  4. Call av_resample() to do the actual resampling on your audio buffer.
  5. When you’re done with the resampling context, delete it with av_resample_close().
  6. Finally, link your application against avcodecavutil, and zlib (it won’t work on Linux without this one).

Here it is in pseudocode:

#include "libavcodec/avcodec.h"

avcodec_init();

struct AVResampleContext* ctx = av_resample_init( ... );

av_resample( ctx, ... );

av_resample_close( ctx );

That’s it… seriously!

Sample Code (Linux):

Here’s a sample program I wrote that takes a raw 44.1kHz/16bit/mono audio file and plays it back using the pulseaudio API. The catch is that it allows you to specify a “skew” parameter which will cause the audio to dynamically speed up and slow down (via resampling). The amount of resampling is controlled by a sine wave, which is what drives the speed changes.

Download: resample.tar.bz

To unpack and build, type:

$ tar -xjvf resample.tar.bz
$ make

First, run the sample with no skew:

$ ./resample audio_16b_44k_mono_pcm_raw 0

Now, try it with a heavy skew:

$ ./resample audio_16b_44k_mono_pcm_raw -10000

Tagged with:  

When rendering graphics or video to the screen, it’s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called “tearing”… where the video appears to be torn horizontally down the middle (see picture). I’ve been looking for a good explanation to share about why video tearing occurs and how to solve it (from a technical perspective). I found the following thread over at [H]ard|Forum, which I think does a pretty good job.

For the thread “How VSync works, and why people loathe it“:

There is a technique called triple-buffering that solves this VSync problem. Lets go back to our 50FPS, 75Hz example. Frame 1 is in the frame buffer, and 2/3 of frame 2 are drawn in the back buffer. The refresh happens and frame 1 is grabbed for the first time. The last third of frame 2 are drawn in the back buffer, and the first third of frame 3 is drawn in the second back buffer (hence the term triple-buffering). The refresh happens, frame 1 is grabbed for the second time, and frame 2 is copied into the frame buffer and the first part of frame 3 into the back buffer. The last 2/3 of frame 3 are drawn in the back buffer, the refresh happens, frame 2 is grabbed for the first time, and frame 3 is copied to the frame buffer. The process starts over. This time we still got 2 frames, but in only 3 refresh cycles. That’s 2/3 of the refresh rate, which is 50FPS, exactly what we would have gotten without it. Triple-buffering essentially gives the video card someplace to keep doing work while it waits to transfer the back buffer to the frame buffer, so it doesn’t have to waste time. Unfortunately, triple-buffering isn’t available in every game, and in fact it isn’t too common. It also can cost a little performance to utilize, as it requires extra VRAM for the buffers, and time spent copying all of them around. However, triplebuffered VSync really is the key to the best experience as you eliminate tearing without the downsides of normal VSync (unless you consider the fact that your FPS is capped a downside… which is silly because you can’t see an FPS higher than your refresh anyway).

If the thread is ever unavailable, you can download a PDF version HERE.

Tagged with:  

Being a parent now, I found this commercial pretty funny.

Tagged with:  

My friend Nick brought this video to my attention. It shows how small $100 million dollars is compared to the entire US budget. What really stood out to me was how much of the budget is dominated by welfare handouts… looks like over 80%. I guess we are “all socialists now.”

(requires Adobe Flash plugin… click HERE to watch it on YouTube)

Tagged with:  

Video: Charlie Hunter – Recess

On April 28, 2009, in Tunes and Grooves, by Tom

I found my Charlie Hunter CD recently and I’ve been enjoying listening to him again. He’s an amazing musician apart from the fact that he plays the bass and guitar simultaneously. YouTube didn’t exist when I first got into him, and it’s nice now to be able to watch him play. Enjoy!

(requires Adobe Flash plugin… click HERE to watch it on YouTube)

If this video ever gets deleted from YouTube, you can download it HERE.

Tagged with: