30 December, 2009

Create ISO Image From Directory

Occasionally it's useful to create a CD/DVD ISO image from a list of files contained in a directory. For instance, if you're interested in archiving a bunch of files to be later burned to a CD/DVD.

This can be done by using the mkisofs command which stands for 'make ISO filesystem'.

If you have a list of directories like the following:

user@debian:/media/ehd/tmp$ ls -l
total 2802468
drwxr-xr-x 3 root root 4096 2009-12-29 13:01 disc01
drwxr-xr-x 3 root root 4096 2009-12-29 13:01 disc02
drwxr-xr-x 3 root root 4096 2009-12-29 13:02 disc03
drwxr-xr-x 3 root root 4096 2009-12-29 13:03 disc04
drwxr-xr-x 3 root root 4096 2009-12-29 13:05 disc05
drwxr-xr-x 3 root root 4096 2009-12-29 13:06 disc06
drwxr-xr-x 3 root root 4096 2009-12-29 13:08 disc07
drwxr-xr-x 3 root root 4096 2009-12-29 13:09 disc08
drwxr-xr-x 3 root root 4096 2009-12-29 13:10 disc09
drwxr-xr-x 3 root root 4096 2009-12-29 13:10 disc10
drwxr-xr-x 3 root root 4096 2009-12-29 13:12 disc11
user@debian:/media/ehd/tmp$


You can create individual ISO images for each directory by issuing the following command:

$ mkisofs -o disc02.iso -J disc02


The ISO image will preserve the directory structures and file names found under disc02.

Cheers

27 December, 2009

Embedded MPlayer in Tk

Ok, something a bit more interesting.

I've been using mplayer since 'bout 94 (near as I can recall), it's has been and continues to be my video player of choice. In spite of that, I still learn things now and again. Today was an instance of learning a little something about it I didn't know before.

Mplayer supports a slave mode, this was news to me. In that mode it is geared to receive commands to manipulate the player. The intention is to allow the creation of front-ends which are plentiful for that reason. I found this especially useful in embedding Mplayer into a Tk window and binding Tk controls to the player.

Below is a rough sampling of how it can be done.


#!/usr/bin/tclsh
package require Tk

proc Exit { } {
exit
}

proc Play { } {
upvar #0 playerId playerId
puts $playerId "pause"
}

proc ReadPipe {chan} {
upvar #0 playerId playerId
set d [read $chan]
foreach line [split $d \n] {
set line [string trim $line]
if {[regexp {^\*\*\* screenshot '(.*?)' \*\*\*} $line -> filename]} {
# delay to permit the file to appear
after 250 [list OnScreenshot $filename]
}
}
if {[eof $chan]} {
fileevent $chan readable {}
close $chan
set playerId ""
}
}

proc EmbedPlayer { w } {
upvar #0 fileList fileList
upvar #0 playerId playerId
set cmd mplayer
lappend cmd -slave -vf scale=1540:1050 -wid [winfo id $w] -idle

set pipe [open |$cmd r+]
fconfigure $pipe -blocking 0 -buffering line
fileevent $pipe readable [list ReadPipe $pipe]
set playerId $pipe

puts $playerId "load [lindex $fileList 0]"
set fileList [lrange $fileList 1 end]
}

proc main { { fileList [list]} } {
wm title . "User Interface"
wm protocol . WM_DELETE_WINDOW [list Exit]
wm withdraw .

frame .video -width 1540 -height 800
grid .video -sticky news

frame .controls -width 1540 -height 100
button .play -text "Play" -command Play
grid .play -sticky news

grid rowconfigure . 0 -weight 1
grid columnconfigure . 0 -weight 1


option add *tearOff false
. configure -menu [menu .menu]
.menu add cascade -label File -menu [menu .menu.file]
.menu.file add command -label Exit -command Exit
bind .video {
bind %W
{}
EmbedPlayer %W
}
wm deiconify .
}

#---main---
set fileList $argv
main


I stripped this segment out of a more involved utility I'm working on so it isn't as clean as it could be.

Issue ./mplayerUi and Bobs Your Uncle.

Playing Video On Desktop

I've been screwing around with MPlayer for a bit today. Specifically, I was trying to configure it to display on the desktop rather than a movable window.

I found a couple things worth noting:
1) if you don't have hw support you won't be able to apply it to your background nor scale it. Check for xv support by issuing the 'xvinfo' command. I found I didn't have the proper driver configured and therefore had to tweak my xorg.conf
2) The required command to scale the video up (in my case) isn't intuitive.

I had success with the following command:


$ mplayer -vf scale=1024:720 -rootwin DesiresAndDiversions.mpg


Cheers.

Diamond Radeon HD 3450 X Configuration

Spent some time today playing with Mplayer. Got stuck applying the video to the root window because I didn't have xv support enabled. As a result, did some Googlin' and had to reconfig my xorg.conf; attached.


$ cat /etc/X11/xorg.conf
Section "Monitor"
Identifier "Configured Monitor"
EndSection

Section "Screen"
Identifier "Default Screen"
Monitor "Configured Monitor"
Device "Configured Video Device"
DefaultDepth 24
EndSection

Section "Module"
Load "glx"
Disable "dri2"
EndSection

Section "Device"
Identifier "Configured Video Device"
Driver "fglrx"
EndSection

Section "DRI"
Mode 0666
EndSection

Section "Extensions"
Option "Composite" "Enable"
EndSection

26 December, 2009

Text-to-Speech

It's been quite some time since I've authored a post. Been busy at work and haven't found too much time to find new things to play with.

I did however take a little time over Christmas to rattle on the keyboard. I found a text-to-speech utility that proves promising to play with.


# apt-get install espeak


Then, simply run it.


$ espeak "hello, how are you doing?"


Easy, peezy.

22 November, 2009

Playing On-Line Station Streams

I have a couple of my favorite radio stations here in the twin cities that I enjoy listening to. Trouble is since 99% of the world is Windoze users they tend to author their streaming links to the masses. I found that you can play the audio streams from these stations by issuing the proper commands.

93X KXXR-FM

$ mplayer http://citadelcc-kxxr-fm.wm.llnwd.net/citadelcc_KXXR_FM


92 KQRS

$ mplayer http://citadelcc-kqrs-fm.wm.llnwd.net/citadelcc_KQRS_FM

20 November, 2009

Mplayer Dvd Audio

I've been burning DVDs like I have for the past couple years. Until recently I've not had any issues playing them back, but the latest discs have had trouble playing.
The audio track seems to be defaulted to commentary, which is at best annoying.

I found how to change the audio channel by playing with mplayer using the following:


$ mplayer dvd://1 -alang en


Cheers.

06 October, 2009

Quick-n-Dirty CD Replication

Assuming you have a CD that isn't copy protected sometimes you want to replicate it without user interface based tools....the command line.

Real quick, but you can replicate the disk contents by generating an ISO image by issuing the command:

dd if=/dev/sr0 of=PingBootDisk.iso


This assumes the CDROM is mounted at /dev/sr0, you can establish the device by issuing the 'mount' command and examining the file systems.

Next, use cdrecord; the trick again is to establish the device. Isolate the device by issuing the following command:

cdrecord -scanbus


Then burn the disk ISO image by issuing the following:

cdrecord -v dev=1,0,0 PingBootDisk.iso

24 September, 2009

Mplayer Swiss Army Knife

Mplayer adopts the 'can do' attitude as a media player. Generally, this utility will play most anything, employs most standard codecs and many that you'll likely never need. If you have a video file, likely you can play it with Mplayer...including raw data.

A recent program I was working on grabbed raw LVDS data streams from a Flir infared camera. First task, confirm the video output is reasonable. Cue investigation of how to play raw data streams without requiring encoding. Mplayer met this need quite nicely. For fun, I thought I'd post some of our findings, hopefully you can find them useful.

Lets start with generating our own raw video stream:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <assert.h>

int main()
{
static const int NumFrames = 10;
static const int Width = 640;
static const int Height = 480;

printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
std::string fileName="/tmp/video.raw";
printf("(%s:%d) fileName='%s'\n",__FILE__,__LINE__,fileName.c_str());
int fp=open(fileName.c_str(),O_CREAT|O_WRONLY|O_TRUNC);

for (int i=0; i<NumFrames; ++i)
{
unsigned char frame[Width*Height];

// generate frame; white box, framed with black lines
memset (frame,255,Width*Height);
for(int c=0; c<Width; ++c) frame[c+Width*0]=0;
for(int c=0; c<Width; ++c) frame[c+Width*(Height-1)]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h+(Width-1)]=0;

// write frame contents to file
for(int k=0; k<Width*Height; ++k)
{
void* tmp=(void*)(frame+k);
int ret=write(fp,tmp,sizeof(unsigned char));
assert(ret==sizeof(unsigned char));
}
}

close(fp);

printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}


The above code simply generates a sequence of 10 640x480 8-bit grayscale frames, the content of each frame a white background framed with a black one-pixel wide border.

You can play the video contents of this file by issuing the following Mplayer command:

$ mplayer -demuxer rawvideo -rawvideo w=640:h=480:y8:size=307200:fps=1 /tmp/video.raw

A few things worth mentioning; first, since this is a raw video the frame size must be specified (ie. w=640:h=480), the frame rate (fps=1) must be specified as well or it will default to 24fps, giving us little time to review the contents of the video. Lastly, the size=307200 (640*480) is optional at for this format, but will become relevant in later examples. By default, the size will be defined by the width*height, so for this example you could simply not specify the value and all would still be well.

That was fun, but let's give it a little more snap. Suppose you wanted to add some frame metadata following each frame. We'll modify our above example a bit, each frame will be followed by a fixed 28-byte character string identifying the frame number.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <assert.h>

int main()
{
static const int NumFrames = 10;
static const int Width = 640;
static const int Height = 480;

printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
std::string fileName="/tmp/video.raw";
printf("(%s:%d) fileName='%s'\n",__FILE__,__LINE__,fileName.c_str());
int fp=open(fileName.c_str(),O_CREAT|O_WRONLY|O_TRUNC);

for (int i=0; i<NumFrames; ++i)
{
unsigned char frame[Width*Height];

// generate frame; white box, framed with black lines
memset (frame,255,Width*Height);
for(int c=0; c<Width; ++c) frame[c+Width*0]=0;
for(int c=0; c<Width; ++c) frame[c+Width*(Height-1)]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h+(Width-1)]=0;

// write frame contents to file
for(int k=0; k<Width*Height; ++k)
{
void* tmp=(void*)(frame+k);
int ret=write(fp,tmp,sizeof(unsigned char));
assert(ret==sizeof(unsigned char));
}
//write some metadata
char metaData[28];
sprintf(metaData,"frame%04d",i);
assert(write(fp,metaData,sizeof(metaData))==sizeof(metaData));
}

close(fp);

printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}
Now the frame size becomes a required argument, since the frame size must now account for the metadata, otherwise the metadata would be interpreted as video and you'd have a mess. You can play the above generated video by issuing the command as follows:

$ mplayer -demuxer rawvideo -rawvideo w=640:h=480:y8:size=307228:fps=1 /tmp/video.raw

Ok, now we've learned how to play video with metadata. Our last trick will be playing video with a initial video header.

Let's start by adding some video metadata at the beginning of the video, a 200-byte string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <assert.h>

int main()
{
static const int NumFrames = 10;
static const int Width = 640;
static const int Height = 480;

printf("(%s:%d) main process initializing\n",__FILE__,__LINE__);
std::string fileName="/tmp/video.raw";
printf("(%s:%d) fileName='%s'\n",__FILE__,__LINE__,fileName.c_str());
int fp=open(fileName.c_str(),O_CREAT|O_WRONLY|O_TRUNC);

char videoMetaData[200];
sprintf(videoMetaData,"some cool video");
assert(write(fp,videoMetaData,sizeof(videoMetaData))==sizeof(videoMetaData));

for (int i=0; i<NumFrames; ++i)
{
unsigned char frame[Width*Height];

// generate frame; white box, framed with black lines
memset (frame,255,Width*Height);
for(int c=0; c<Width; ++c) frame[c+Width*0]=0;
for(int c=0; c<Width; ++c) frame[c+Width*(Height-1)]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h]=0;
for(int h=0; h<Height; ++h) frame[0+Width*h+(Width-1)]=0;

// write frame contents to file
for(int k=0; k<Width*Height; ++k)
{
void* tmp=(void*)(frame+k);
int ret=write(fp,tmp,sizeof(unsigned char));
assert(ret==sizeof(unsigned char));
}
//write some metadata
char metaData[28];
sprintf(metaData,"frame%04d",i);
assert(write(fp,metaData,sizeof(metaData))==sizeof(metaData));
}

close(fp);

printf("(%s:%d) main process terminating\n",__FILE__,__LINE__);
return EXIT_SUCCESS;
}


You play this form of video by specifying a start byte offset of 200 and you're set.

$ mplayer -demuxer rawvideo -rawvideo w=640:h=480:y8:size=307228:fps=1 -sb 200 /tmp/video.raw

20 September, 2009

Streaming with FFMpeg

For work I've been playing with VLC to support some streaming experiments for the program I'm working on. In the process of installing VLC it became obvious the vast number of package dependencies it's reliant on.

So, for fun, I played with streaming via FFMpeg at home. Below are my findings.

Assuming you have FFMpeg already installed on your machine, there are 3 steps:

1) start the ffserver application with appropriate configuration file.
2) start ffmpeg to redirect the input to the stream
3) view with video client

FFServer Setup
The ffserver utility is installed as part of the FFMpeg package, no need to install it explicitly. You do however need to author an appropriate configuration file. Below is the configuration file I've used as a starting point.

$ cat ffserver.conf
Port 8090
# bind to all IPs aliased or not
BindAddress 0.0.0.0
# max number of simultaneous clients
MaxClients 10
# max bandwidth per-client (kb/s)
MaxBandwidth 10000
# Suppress that if you want to launch ffserver as a daemon.
NoDaemon


File /tmp/feed1.ffm
FileMaxSize 5M


# FLV output - good for streaming

# the source feed
Feed feed1.ffm
# the output stream format - FLV = FLash Video
Format flv
VideoCodec flv
# this must match the ffmpeg -r argument
VideoFrameRate 10
# generally leave this is a large number
VideoBufferSize 80000
# another quality tweak
VideoBitRate 200
# quality ranges - 1-31 (1 = best, 31 = worst)
VideoQMin 30
VideoQMax 31
VideoSize 352x288
# this sets how many seconds in past to start
PreRoll 0
# wecams don't have audio
Noaudio


# ASF output - for windows media player

# the source feed
Feed feed1.ffm
# the output stream format - ASF
Format asf
VideoCodec msmpeg4
# this must match the ffmpeg -r argument
VideoFrameRate 10
# generally leave this is a large number
VideoBufferSize 80000
# another quality tweak
VideoBitRate 200
# quality ranges - 1-31 (1 = best, 31 = worst)
VideoQMin 30
VideoQMax 31
VideoSize 352x288
# this sets how many seconds in past to start
PreRoll 0
# wecams don't have audio
Noaudio

$


Next, you need to run ffserver as follows:

$ ffserver -f ffserver.conf


FFMpeg Setup
The ffmpeg utility feeds the server. The following example uses a quick cam as the source, redirecting through the video server to be viewed by the clients. Worth noting, the ffserver configuration file specifies a frame rate, in this case 10fps, which must match the command line specification of ffmpeg.


$ ffmpeg -r 10 -s 352x288 -f video4linux -i /dev/video0 http://localhost:8090/feed1.ffm



Video Client Setup
Lastly, test the feed using a video client. For our example, we'll use mplayer as follows:

$ mplayer http://localhost:8090/test.asf

Play nice.

09 September, 2009

Redirecting Sound with rDesktop

I've been working with VirtualBox for the past few months. I've grown to love it, and consider virtualization as one of the most compelling technologies we've seen in the past decade.

Running VMs headless has quite a few advantages. For instance, we're bundling X VMs on a server and serving out to less capable processors via RDP clients. The latest challenge was redirecting sound to the client processor. Like most things, pretty simple to do...once you've done it.

Thought it was worth a quick note:

Assuming you've started a VM with remote display enabled, such as:

$ VBoxHeadless -startvm WinXp -vrdp on -vrdpport 8000


To establish an RDP connection (assuming host IP of 192.168.1.27):


$ rdesktop 192.168.1.27:8000



$ rdesktop 192.168.1.27:8000 -r sound:local:oss

08 September, 2009

Older Debian Releases

Perhaps I'm living up to my name, the fat slow kid, but if I'm honest I have a hell of a time locating previous releases of Debian.

I search and I search and I search some more; after finally finding them I thought it was worth a quick post.

http://www.debian.org/releases/

For 'etch', follow the links to:
http://www.debian.org/releases/etch/debian-installer/

With the common redirects pressing you toward the latest-n-greatest sometimes its difficult to get the older version you're after.

Cheers.

21 August, 2009

VirtualBox - Restoration Media Installation

A curiosity I found was I have had success using OS restoration disks to create virtual machines. In particular a government program restoration disc used to reimage laptops, I can't get into details.

In order to make this work however I found I needed to enable passthrough on the CD/DVD drive, otherwise it hung prior to detecting the media.

Just a note, hope someone finds it valuable.

Multiple RDP Connections with VirtualBox

I was noodling through the latest VirtualBox 3.0.4 Manual and found the solution to a problem I've been chasing for now 2 months.

We've been trying to incorporate multiple user connections to a virtual machine to allow desktop sharing. The intention was the users would need to coordinate actions and share the desktop. The primary use was to support remote monitoring of a user's session while allowing the either user to interact as required.

VirtualBox 3.0.4 introduced a new vrdpmulticon specifier that appears to have addressed the issue.

From the command line you need to issue the following command to enable multiple RDP connection sharing, the effect is to allow multiple connections share a RDP server session.


$ VBoxManage modifyvm WinXp --vrdp on
$ VBoxManage modifyvm WinXp --vrdpmulticon on

Where in this case the name of the virtual machine is WinXp.

I've struggled with this for the past couple months. The solutions, 'til now, have been restricted to 'hacking WinXp' (a legal mine field) or upgrading to server 200x.

Hope you find this as useful as I do.
Cheers.

20 August, 2009

Capturing Video From QuickCam Express Using FFMpeg

Another quick post.

You can capture motion video from your QuickCam Express USB camera (assuming properly configured) by issuing the following command:


$ ffmpeg -r 15 -s 352x288 -f video4linux -i /dev/video0 /tmp/video.avi


This will capture at a 15 fps frame rate at the specified resolution.

Cheers.

19 August, 2009

Installing LibDvdCss2 on Debian Lenny

Real quick post on how to install libdvdcss on Lenny. This is necessary to play encrypted disks with totem (and other video players).



# echo "deb http://debian-multimedia.org lenny main" >> /etc/apt/sources.list
# echo "deb-src http://debian-multimedia.org lenny main" >> /etc/apt/sources.list
# apt-get update
# apt-get install libdvdcss2

18 August, 2009

Installation of QuickCam Express on Debian Lenny

2 apt-get install module-assistant
3 apt-get install qc-usb-source
4 apt-get install xawtv
6 m-a prepare
7 cd /usr/src/
8 tar -jxvf ./qc-usb.tar.bz2
9 cd modules/qc-usb/
10 make
11 make install
28 m-a -f build qc-usb
29 m-a -f install qc-usb
33 modprobe -l
35 modprobe quickcam
36 xawtv -hwscan

Debian List Installed Packages

Short-n-sweet; In order to list the currently installed packages do the following:



$ dpkg --get-selections

12 August, 2009

Debian Lenny - FFMpeg

A challenge of migrating to a new distribution will always be the subtleties that each update brings.

For example, I assume this is because Debian strives to ensure that only open-source utilities are distributed my recent update to 'Lenny' left me with an FFMpeg distro that doesn't support encoding MS-MPEG4v2 videos.

As a result, you have to rebuild from source as follows:


xion:/home/user/ffmpeg-0.5$ ./configure --enable-x11grab --enable-gpl --prefix=/usr
xion:/home/user/ffmpeg-0.5$ su
xion:/home/user/ffmpeg-0.5# make install


I chose the /usr destination to overwrite any existing installation, otherwise you'd have to resolve path issues to ensure you're running the 'right' binary.

Tah.

09 August, 2009

Debian Lenny Sound Installation

I just installed 'Lenny' on my workstation. I struggled for a couple hours trying to get the sound card configured.

After the installation I found the sound card wasn't working properly.

To resolve, I switched user to root, ran alsaconf, selected the CA0106 Alsa Mixer, ran alsamixer and set the volume accordingly.

It's also worth noting that I opened the 'Volume Control Preferences', selected the CA0106 device and selected the Analog Front selection to allow volume control from the panel.

10 July, 2009

Convert Color Video To GrayScale

I've recently found it useful to convert color video into grayscale video. I found the following to be effective in doing so.


$ ffmpeg -y -i /tmp/video.avi -s 640x480 -pix_fmt gray -vcodec rawvideo /var/tmp/video.avi


I haven't however found a means to re-encode the grayscale into an alternative codec (sigh).

06 July, 2009

Narrowing Your Google Search

I was just surfing for ServiceMix documentation and came across instructions at a website that suggested searching their site for specific info by using Google and constraining the search to their site.

Paint my ass and call me Sally.....I didn't know you could do that.

Seems that you can constrain a search to a given site by specifying a site: directive.

For example,

site:fatslowkid.blogspot.com imagemagick


This'll limit your search to the fatslowkid.blogspot.com site, looking for instances of imagemagick.

Cheers.

03 July, 2009

ImageMagick Frame Differences

ImageMagick has some image processing utilities built right in. I recently found a means to display the differences between 2 PNM images.

By using these image processing utilities you can compare the following images to detect the changes between frames by using the following command:

$ convert frame00000002.bmp frame00000001.bmp -compose difference -composite -threshold 0 -negate diff.bmp




The resultant image is as follows:



Another side note that's worth mentioning, you don't have to redirect the results to a file. You can instead redirect the output to stdout and pipe it into the display utility for immediate rendering to screen; as follows:

$ convert frame00000002.bmp frame00000001.bmp -compose difference -composite -threshold 0 -negate - | display



Gotta love the command pipe!!

30 June, 2009

Power of the Pipe

For quite some time I've it's been a mystery to me why many Unix-flavored toolsuites offer a command line interface supporting inputting or outputting to stdin/stdout respectively.

For example, ffmpeg can utilize stdin in leu of a input file by specifying -; similarly it can utilize stdout in leu of an output file using the same - specifier.

I've recently become aware of how useful this option can be. In particular it allows you to bypass creating unnecessary temporary files.

For example, using ffmpeg you can redirect the output to stdout and into mplayer to review the impacts of varying codecs and video quality specifiers.


$ ffmpeg -i /var/tmp/foo.mpg -f asf - | mplayer -cache 8192 -


Similarly, you can make use of the similar feature with ImageMagick like so:

$ convert Lenna.jpg - | display -


In each case, redirecting to stdout and piping to a consuming display utility eliminates the need for creating a temporary file.

26 June, 2009

Drawing Primitives with ImageMagick

ImageMagick offers far more than simple image conversion utilities. It also extends to you the ability to create new images using drawing primitives. I've recently found this useful in creating artificially created videos use to test image processing and tracking techniques. The following script supports creating a series of circular targets in a newly created frame. By creating a series of frames, stitching them together with FFMpeg and you can create a video of moving targets of know positions. Useful for testing algorithms.

Later.


#!/usr/bin/tclsh

proc createFrame { fileName imageL targets } {
array set image $imageL
set tL ""

foreach e $targets {
switch [lindex $e 0] {
circle
{
set x0 [lindex [split [lindex $e 1] ,] 0]
set y0 [lindex [split [lindex $e 1] ,] 1]
set r [lindex $e 2]
set x1 [expr $x0 + $r]
set y1 $y0
set tL [concat $tL "-fill red -draw 'circle $x0,$y0 $x1,$y1'"]
}
}
}

set cmd "/usr/bin/convert -size $image(width)x$image(height) xc:white $tL $fileName"
puts $cmd
exec bash -c $cmd
}

#---main---
set image(width) 640
set image(height) 480
set fileName /tmp/frame00000001.pnm
lappend targets [list circle 320,240 10]
lappend targets [list circle 100,100 10]
createFrame $fileName [array get image] $targets

19 June, 2009

Cpu Load Monitoring

We've recently had explore collecting and analyzing CPU resource loading metrics for our project. The host OS is Linux 2.6 based and rather than install a performance-specific set of utilities we aimed at utilizing readily available services.

Ask any Linux weenie what CPU loading they have been experiencing and most will respond by starting the top utility. Top is available on most Unix distributions, is a well known utility and has pretty much stood the test of time. For those reasons it seemed obvious to incorporate it into a performance monitoring data collection and analysis tool suite.

The following Tcl script takes two arguments, the first an output file which will be populated with the redirected top log file, the second is a duration (in seconds) of how long to monitor the performance. After the raw collection has completed the script parses the log, extracts the CPU loading metrics and outputs a median and mean CPU processing load expressed in percentage of utilization.

It's worth noting that the script incorporates searching for the regular expression *Cpu* to find the top line item holding the Cpu metrics. As a result, if you have a process running that matches *Cpu* you'll find the script errors out during processing of the log file. I'll leave it as a lesson to the reader how to correct (wink).

We've extended on the same principle to monitor network activities.

Have fun.


#!/usr/bin/tclsh

proc log { msg } {
# puts stderr __$msg
}

proc mean { L } {
set sum 0.0
foreach e $L {
set sum [expr $sum + $e]
}
return [expr $sum / [llength $L].]
}

proc median { L } {
set L1 [lsort -real $L]
return [lindex $L1 [expr [llength $L1] / 2]]
}

proc process { fileName } {
set fp [open $fileName r]
while { [gets $fp line] >= 0 } {
switch -glob -- $line {
*Cpu*
{
log "processing line '$line'"
set el [split $line ,]
set userLoad [string trimleft [lindex $el 0] "Cpu(s):"]
set sysLoad [lindex $el 1]
set niceLoad [lindex $el 2]
set idleLoad [lindex $el 3]
log "parsing $userLoad"
log "parsing $sysLoad"
log "parsing $niceLoad"
log "parsing $idleLoad"
set userLoad [lindex [split $userLoad \%] 0]
set sysLoad [lindex [split $sysLoad \%] 0]
set niceLoad [lindex [split $niceLoad \%] 0]
set idleLoad [lindex [split $idleLoad \%] 0]
log "extracted $userLoad"
log "extracted $sysLoad"
log "extracted $niceLoad"
log "extracted $idleLoad"
# puts [expr $userLoad+$sysLoad+$niceLoad+$idleLoad]
lappend L [expr 100.0-$idleLoad]
}
}
}
close $fp
puts "mean cpu load: [mean $L]"
puts "median cpu load: [median $L]"
}

proc monitorCpuLoad { fileName duration } {
catch { exec top -b -n $duration -d 1 > $fileName }
process $fileName
}

proc help { } {
upvar #0 argv0 argv0
puts stderr "usage: $argv0 \[logFileName\] \[duration\]"
exit
}

#---main---
if { [llength $argv] != 2 } {
help
}
monitorCpuLoad [lindex $argv 0] [lindex $argv 1]



18 June, 2009

Capturing Radio Broadcast Streams with Mplayer

My wife and I took our honeymoon in Australia and I can admit that there are numerous occasions where I hunger for a bit of Aussie. I recently explored how to capture an audio stream to play back on my MP3 player (since our office frowns on streaming).

This is how I've been capturing Triple-J streams for fun;


$ mplayer http://202.6.74.107:8060/triplej.mp3 -dumpstream -dumpfile /tmp/audio.mp3

12 June, 2009

Screen Capture with FFmpeg

Sometimes it's useful to capture the display output as a means of archiving a procedure or to demonstrate a user experience. The following command will capture the display region 1680x1050 at 30fps for 90 seconds and shrink it to a 640x480 video at near raw resolution (fixed quantizer scale of 1).

The important thing is to confirm your ffmpeg format supports x11grab, otherwise you'll get the following error:

Unknown input or output format: x11grab



ffmpeg -y -f x11grab -r 30 -s 1680x1050 -i :0.0 -t 90 -qscale 1 -s 640x480 out.mpg


As you can imagine, capturing 30fps adds significant resource loading, if you so choose you can down-sample the frame rate but you may need to use an alternative encoder for non-compliant frame rates of some codecs.

The MJPEG encoder seems to work well enough for slow frame rates, like 1 Hz.


ffmpeg -y -f x11grab -r 1/1 -s 1680x1050 -i :0.0 -t 90 -qscale 1 -s 640x480 -vcodec mjpeg out.avi

07 June, 2009

Code Monkey

This video always makes me smile:

06 June, 2009

Controlling VirtualBox Guest Actions

On the Guest:
vboxcontrol guestproperty set TestState ready
vboxcontrol guestproperty wait foo
"C:\Program Files\Windows Media Player\wmplayer.exe" /prefetch:1

On the Host:
#!/bin/bash

retVal=0
retVal=`VBoxManage guestproperty get WinXp TestState | grep Value | cut -f 2 -d \ `
echo $retVal
while [ $retVal != ready ]; do
echo foo
sleep 1
retVal=`VBoxManage guestproperty get WinXp TestState | grep Value | cut -f 2 -d \ `
done

VBoxManage guestproperty set WinXp foo 1


22 May, 2009

ImageMagick - Montage

I love FFMpeg and ImageMagick. Armed with both, you can create some pretty interesting things. For example, you can create a frame consisting of 4 images by issuing the following command:


montage -geometry 720x480+0+0 -tile 2x2 /var/tmp/00000001.jpg /var/tmp/00000002.jpg /var/tmp/00000003.jpg /var/tmp/00000004.jpg /tmp/output.jpg


This will take these 4 images:





To create the following resultant image:

A framed image like the resultant isn't particularly interesting, unless you incorporate a series of them into a video. For example, at work we wished to determine what frame rate would be necessary to drive a vehicle exclusively using a camera. We investigated this by creating a montage video stream with varying frame rates in each frame.

Another fine use would be comparison of file size using alternative video comparisions. For example, imagine a montage frame with each frame demonstrating a different JPEG image, file size and compression ratio. Heck, you could even generate your very own composite video with each of Charlies Angels in each of their own frames. The uses are endless :)

20 May, 2009

FFmpeg Ninja Moves - part 4

Maintaining video quality during conversion can be a primary concern when converting to an alternative format while maintaining the necessary video quality.

By default, the output codec will utilize a default set of encoder quality specifiers. You can override these values by specifying -sameq, -qmin, -qmax or -qscale factors.

The -sameq specifier tells FFMpeg to maintain the same video quality as the source video file.

$ ffmpeg -i /tmp/video.avi -sameq /tmp/video.mpg


The qmin and qmax specifiers constrain the q-factors to a user-specified range. This applies to variable bit rate output streams. Specifying a narrow range will ensure consistent quality. Specifying a highly constrained, high quality factor will give you a good quality output video.

$ ffmpeg -i /tmp/video.avi -qmin 1 -qmax 1 /tmp/video.mpg


Constraining the scale factor to a single numeric can be alternatively done by specifying -qscale as follows.

$ ffmpeg -i /tmp/video.avi -qscale 1 /tmp/video.mpg


Note, the lower the value the higher the video quality.

18 May, 2009

FFmpeg Ninja Moves - part 4

Continuing on our FFMpeg trek, this post will focus on manipulating frame sizes; specifically, cropping, resizing and padding.

Cropping
Selectively cropping out a portion of each frame in the video allows you to focus on particular regions. The input video has 720x480 dimensions, suppose you were only interested in the inner 360x240 frame contents. You can crop the video frames by specifying the left, right, top and bottom crop bands (specified in pixels). As an example, the following command crops the innter 360x240 frame contents.

$ ffmpeg -i /tmp/video.avi -croptop 120 -cropbottom 120 -cropleft 180 -cropright 180 /var/tmp/video.avi

Resizing
If instead of cropping the image you wish to resize it, you can specify a desired frame size WxH. For example, if you wish the output video file dimensions to consist of 360x240 you can specify the -s size specifier as follows:

$ ffmpeg -i /tmp/video.avi -s 360x240 /var/tmp/video.avi

Unlike cropping, all frame contents are retained but the lesser dimensions gives the effect of dropping every other pixel contents.

Padding
If you require expanding the video dimensions you can pad the left, right, top and bottom to attain the desired frame dimensions. To convert the 720x480 video dimensions to 800x600 you can specify

ffmpeg -i /tmp/video.avi -padtop 40 -padbottom 40 -padleft 60 -padright 60 -padcolor FFFFFF /var/tmp/video.avi

I specified a white pad color to allow you to see the pad effects. A keen reader will notice that in order to preserve the aspect ratio the output video is actually 840 x 560.

16 May, 2009

FFmpeg Ninja Moves - part 3

Continuing on, this post will focus on time with respect to video files.

Altering Video Frame Rate
Let's start by playing with the frame rate. Given a 30 frames/sec input file, we can specify a desired alternative frame rate for the output file by specifying the rate specifier.

We can downsample to 5 frames per second by issuing the following command:

$ ffmpeg -i /tmp/video.avi -r 5/1 /var/tmp/video.avi


$ ffmpeg -i /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/tmp/video.avi':
Duration: 00:00:57.4, start: 0.000000, bitrate: 297 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 5.00 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file




Similarly, we can upsample to 60 frames per second by issuing the following:

$ ffmpeg -y -i /tmp/video.avi -r 60/1 /var/tmp/video.avi
$ ffmpeg -i /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 889 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 60.00 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


Time-Specified Clip
A common practice concerns extracting a video clip from a video stream. Perhaps you're only interested in the first 2 minutes of the video, perhaps the middle 30 seconds is of interest. In either case, the ability to grab a portion of the video is always valuable. The -ss specifier allows seeking into the input file, the -t duration specifier defines how long a clip you wish; both use seconds as the units.

For example, to seek into the source video 32 seconds and extract the next 2.5 seconds you can specify:

$ ffmpeg -y -i /tmp/video.avi -ss 32 -t 2.5 /var/tmp/video.avi
Repeat
Introducing a repeated video sequence can be a necessary feature to author videos. FFMpeg does not directly support this feature, instead the ability to incorporate multiple video streams allows simultaneous concurrent streams rather than sequential videos. The multiple, simultaneous video streams can be incorporated much like DVD contents allow multiple view angles. FFMpeg however does indirectly allow concatenating videos to give a repeat or sequence of video clips. The trick is to convert your source video files into a concat-able format such as MPEG and simply join them together using the cat utility. For example:


$ ffmpeg -i /tmp/video.avi -sameq /tmp/video.mpg
$ cat /tmp/video.mpg /tmp/video.mpg > /tmp/biggie.mpg

The output file now has 2 iterations of /tmp/video.mpg.

14 May, 2009

FFmpeg Ninja Moves - part 2

In part 1 we showed how to access the help info by specifying the -h command line argument. Paying special attention to the first line shows both the input and output files allow options:


.
.
usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...
Hyper fast Audio and Video encoder
.
.


Note that both the input and output files allow for options. Many typical uses of FFMpeg will not require input options as they can often be implicitly determined from the input file (e.g. frame rate, codec, . . .).

Let's start with 'The Duke', as any warm-blooded American can't help but love this 'one eyed fat-man'.


FFMpeg shows the encoder used is mpeg4, video dimensions of 720x480 and a 30 fps frame rate with mp2 audio. This information is available by specifying an input file with no output file options as follows:

$ ffmpeg -i /tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from '/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 7104 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


We can re-encode this video into an alternative codec such as MS-MPEG4. First, since each FFMpeg installation relies on the available codecs we need to examine what video encoders are available to make our selection:

$ ffmpeg -formats | egrep "Codecs:|EV"
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Codecs:
DEV D asv1
DEV D asv2
DEV D dvvideo
DEV D ffv1
DEVSD ffvhuff
DEVSD flv
DEV D h261
DEVSDT h263
EV h263p
DEVSD huffyuv
EV jpegls
EV ljpeg
DEV D mjpeg
DEVSDT mpeg1video
DEVSDT mpeg2video
DEVSDT mpeg4
DEVSD msmpeg4
DEVSD msmpeg4v1
DEVSD msmpeg4v2

DEV pam
DEV pbm
DEV pgm
DEV pgmyuv
DEV png
DEV ppm
DEV rawvideo
DEV D rv10
DEV D rv20
DEV snow
DEV D svq1
DEVSD wmv1
DEVSD wmv2
DEV D zlib


This installation supports MS-MPEG4 versions 1 & 2. We can therefore re-encode the source video into MS-MPEG4 format, a commonly available codec for Windows (boo, hiss) platforms. You can convert the source video into MS-MPEG4v2 format as follows:

$ ffmpeg -i /tmp/video.avi -vcodec msmpeg4v2 -sameq ~/video.avi

$ ffmpeg -i ~/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/home/lipeltgm/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 6663 kb/s
Stream #0.0: Video: msmpeg4v2, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


By specifying the -vcodec argument, you can force the output file to use the codec you specify. Specifying -vcodec msmpeg4v2 therefore forces the output file to be encoded using MS-MPEG4v2 codec. You should notice that the resultant image is now encoded using msmpeg4v2. You may also notice that the conversion command line specified a -sameq argument which we haven't discussed. Simply put, you may find this argument useful if you wish to retain the source videos quality. The -sameq argument simply applies the 'same quality' as the input video. By not constraining the video quality of the output video the standard defaults will apply which may give you a smaller file size, but a video stream of lesser quality.

In typical use, you'll employ an iterative process of processing an input file, examine the output file results, and re-process the input file until you finally arrive at the desired results. That said, in many cases you'll respecify the same command line, tailoring the options as you see fit. This brings us to the point, FFMpeg will prompt the user for over-write permissions if you specify an output file that already exists. You're prompted for a y/n response when the output file is detected. You can respond 'y' to continue, or if you'd rather not be bothered with the prompts you can specify the -y option which will force overwrite of any existing output file without user prompt.
For example, without specifying the -y argument:


$ ffmpeg -i /tmp/video.avi -vcodec msmpeg4v2 -sameq /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from '/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 7104 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
File '/var/tmp/video.avi' already exists. Overwrite ? [y/N]

Alternatively, you can force overwrite by:

$ ffmpeg -y -i /tmp/video.avi -vcodec msmpeg4v2 -sameq /var/tmp/video.avi

12 May, 2009

FFmpeg Ninja Moves - part 1

Ffmpeg is the Swiss army knife of video converters. Giving a plethora of video and audio conversion options this utility is the framework for arming you with the tools to do significant audio/video processing. This series of posts will explore many of the commonly used features of the utility.

Let's start with the basics; accessing the license and help manuals are as good a place to start as any.


$ ffmpeg -L
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


Accessing the help info shows the extent of options FFmpeg offers.


$ ffmpeg -h
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...
Hyper fast Audio and Video encoder

Main options:
-L show license
-h show help
-version show version
-formats show available formats, codecs, protocols, ...
-f fmt force format
-img img_fmt force image format
-i filename input file name
-y overwrite output files
-t duration set the recording time
-fs limit_size set the limit file size
-ss time_off set the start time offset
-itsoffset time_off set the input ts offset
-title string set the title
-timestamp time set the timestamp
-author string set the author
-copyright string set the copyright
-comment string set the comment
-v verbose control amount of logging
-target type specify target file type ("vcd", "svcd", "dvd", "dv", "dv50", "pal-vcd", "ntsc-svcd", ...)
-dframes number set the number of data frames to record
-scodec codec force subtitle codec ('copy' to copy stream)
-newsubtitle add a new subtitle stream to the current output stream
-slang code set the ISO 639 language code (3 letters) of the current subtitle stream

Video options:
-b bitrate set video bitrate (in kbit/s)
-vframes number set the number of video frames to record
-r rate set frame rate (Hz value, fraction or abbreviation)
-s size set frame size (WxH or abbreviation)
-aspect aspect set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)
-croptop size set top crop band size (in pixels)
-cropbottom size set bottom crop band size (in pixels)
-cropleft size set left crop band size (in pixels)
-cropright size set right crop band size (in pixels)
-padtop size set top pad band size (in pixels)
-padbottom size set bottom pad band size (in pixels)
-padleft size set left pad band size (in pixels)
-padright size set right pad band size (in pixels)
-padcolor color set color of pad bands (Hex 000000 thru FFFFFF)
-vn disable video
-bt tolerance set video bitrate tolerance (in kbit/s)
-maxrate bitrate set max video bitrate tolerance (in kbit/s)
-minrate bitrate set min video bitrate tolerance (in kbit/s)
-bufsize size set ratecontrol buffer size (in kByte)
-vcodec codec force video codec ('copy' to copy stream)
-sameq use same video quality as source (implies VBR)
-pass n select the pass number (1 or 2)
-passlogfile file select two pass log file name
-newvideo add a new video stream to the current output stream

Advanced Video options:
-pix_fmt format set pixel format
-g gop_size set the group of picture size
-intra use only intra frames
-vdt n discard threshold
-qscale q use fixed video quantiser scale (VBR)
-qmin q min video quantiser scale (VBR)
-qmax q max video quantiser scale (VBR)
-lmin lambda min video lagrange factor (VBR)
-lmax lambda max video lagrange factor (VBR)
-mblmin q min macroblock quantiser scale (VBR)
-mblmax q max macroblock quantiser scale (VBR)
-qdiff q max difference between the quantiser scale (VBR)
-qblur blur video quantiser scale blur (VBR)
-qsquish squish how to keep quantiser between qmin and qmax (0 = clip, 1 = use differentiable function)
-qcomp compression video quantiser scale compression (VBR)
-rc_init_cplx complexity initial complexity for 1-pass encoding
-b_qfactor factor qp factor between p and b frames
-i_qfactor factor qp factor between p and i frames
-b_qoffset offset qp offset between p and b frames
-i_qoffset offset qp offset between p and i frames
-ibias bias intra quant bias
-pbias bias inter quant bias
-rc_eq equation set rate control equation
-rc_override override rate control override for specific intervals
-me method set motion estimation method
-me_threshold motion estimaton threshold
-mb_threshold macroblock threshold
-bf frames use 'frames' B frames
-preme pre motion estimation
-bug param workaround not auto detected encoder bugs
-strict strictness how strictly to follow the standards
-deinterlace deinterlace pictures
-psnr calculate PSNR of compressed frames
-vstats dump video coding statistics to file
-vhook module insert video processing module
-intra_matrix matrix specify intra matrix coeffs
-inter_matrix matrix specify inter matrix coeffs
-top top=1/bottom=0/auto=-1 field first
-sc_threshold threshold scene change threshold
-me_range range limit motion vectors range (1023 for DivX player)
-dc precision intra_dc_precision
-mepc factor (1.0 = 256) motion estimation bitrate penalty compensation
-vtag fourcc/tag force video tag/fourcc
-skip_threshold threshold frame skip threshold
-skip_factor factor frame skip factor
-skip_exp exponent frame skip exponent
-genpts generate pts
-qphist show QP histogram
-vbsf bitstream filter

Audio options:
-aframes number set the number of audio frames to record
-ab bitrate set audio bitrate (in kbit/s)
-aq quality set audio quality (codec-specific)
-ar rate set audio sampling rate (in Hz)
-ac channels set number of audio channels
-an disable audio
-acodec codec force audio codec ('copy' to copy stream)
-vol volume change audio volume (256=normal)
-newaudio add a new audio stream to the current output stream
-alang code set the ISO 639 language code (3 letters) of the current audio stream

Advanced Audio options:
-atag fourcc/tag force audio tag/fourcc
-absf bitstream filter

Subtitle options:
-scodec codec force subtitle codec ('copy' to copy stream)
-newsubtitle add a new subtitle stream to the current output stream
-slang code set the ISO 639 language code (3 letters) of the current subtitle stream

Audio/Video grab options:
-vd device set video grab device
-vc channel set video grab channel (DV1394 only)
-tvstd standard set television standard (NTSC, PAL (SECAM))
-ad device set audio device
-grab format request grabbing using
-gd device set grab device

Advanced options:
-map file:stream[:syncfile:syncstream] set input stream mapping
-map_meta_data outfile:infile set meta data information of outfile from infile
-benchmark add timings for benchmarking
-dump dump each input packet
-hex when dumping packets, also dump the payload
-re read input at native frame rate
-loop_input loop (current only works with images)
-loop_output number of times to loop output in formats that support looping (0 loops forever)
-threads count thread count
-vsync video sync method
-async audio sync method
-vglobal video global header storage type
-copyts copy timestamps
-shortest finish encoding within shortest input
-dts_delta_threshold timestamp discontinuity delta threshold
-ps size set packet size in bits
-error rate error rate
-muxrate rate set mux rate
-packetsize size set packet size
-muxdelay seconds set the maximum demux-decode delay
-muxpreload seconds set the initial demux-decode delay
AVCodecContext AVOptions:
-bit_rate E.VA.
-bit_rate_tolerance E.V..
-flags EDVA.
-mv4 E.V.. use four motion vector by macroblock (mpeg4)
-obmc E.V.. use overlapped block motion compensation (h263+)
-qpel E.V.. use 1/4 pel motion compensation
-loop E.V.. use loop filter
-gmc E.V.. use gmc
-mv0 E.V.. always try a mb with mv=<0,0>
-part E.V.. use data partitioning
-gray EDV.. only decode/encode grayscale
-psnr E.V.. error[?] variables will be set during encoding
-naq E.V.. normalize adaptive quantization
-ildct E.V.. use interlaced dct
-low_delay .DV.. force low delay
-alt E.V.. enable alternate scantable (mpeg2/mpeg4)
-trell E.V.. use trellis quantization
-bitexact EDVAS use only bitexact stuff (except (i)dct)
-aic E.V.. h263 advanced intra coding / mpeg4 ac prediction
-umv E.V.. use unlimited motion vectors
-cbp E.V.. use rate distortion optimization for cbp
-qprd E.V.. use rate distortion optimization for qp selection
-aiv E.V.. h263 alternative inter vlc
-slice E.V..
-ilme E.V.. interlaced motion estimation
-scan_offset E.V.. will reserve space for svcd scan offset user data
-cgop E.V.. closed gop
-fast E.V.. allow non spec compliant speedup tricks
-sgop E.V.. strictly enforce gop size
-noout E.V.. skip bitstream encoding
-local_header E.V.. place global headers at every keyframe instead of in extradata
-me_method E.V..
-gop_size E.V..
-cutoff E..A. set cutoff bandwidth
-frame_size E..A.
-qcompress E.V..
-qblur E.V..
-qmin E.V..
-qmax E.V..
-max_qdiff E.V..
-max_b_frames E.V..
-b_quant_factor E.V..
-rc_strategy E.V..
-b_strategy E.V..
-hurry_up .DV..
-bugs .DV..
-autodetect .DV..
-old_msmpeg4 .DV..
-xvid_ilace .DV..
-ump4 .DV..
-no_padding .DV..
-amv .DV..
-ac_vlc .DV..
-qpel_chroma .DV..
-std_qpel .DV..
-qpel_chroma2 .DV..
-direct_blocksize .DV..
-edge .DV..
-hpel_chroma .DV..
-dc_clip .DV..
-ms .DV..
-lelim E.V.. single coefficient elimination threshold for luminance (negative values also consider dc coefficient)
-celim E.V.. single coefficient elimination threshold for chrominance (negative values also consider dc coefficient)
-strict E.V..
-very E.V..
-strict E.V..
-normal E.V..
-inofficial E.V..
-experimental E.V..
-b_quant_offset E.V..
-er .DV..
-careful .DV..
-compliant .DV..
-aggressive .DV..
-very_aggressive .DV..
-mpeg_quant E.V..
-rc_qsquish E.V..
-rc_qmod_amp E.V..
-rc_qmod_freq E.V..
-rc_eq E.V..
-rc_max_rate E.V..
-rc_min_rate E.V..
-rc_buffer_size E.V..
-rc_buf_aggressivity E.V..
-i_quant_factor E.V..
-i_quant_offset E.V..
-rc_initial_cplx E.V..
-dct E.V..
-auto E.V..
-fastint E.V..
-int E.V..
-mmx E.V..
-mlib E.V..
-altivec E.V..
-faan E.V..
-lumi_mask E.V.. lumimasking
-tcplx_mask E.V.. temporal complexity masking
-scplx_mask E.V.. spatial complexity masking
-p_mask E.V.. inter masking
-dark_mask E.V.. darkness masking
-idct EDV..
-auto EDV..
-int EDV..
-simple EDV..
-simplemmx EDV..
-libmpeg2mmx EDV..
-ps2 EDV..
-mlib EDV..
-arm EDV..
-altivec EDV..
-sh4 EDV..
-simplearm EDV..
-h264 EDV..
-vp3 EDV..
-ipp EDV..
-xvidmmx EDV..
-ec .DV..
-guess_mvs .DV..
-deblock .DV..
-pred E.V.. prediction method
-left E.V..
-plane E.V..
-median E.V..
-aspect E.V..
-debug EDVAS print specific debug info
-pict .DV..
-rc E.V..
-bitstream .DV..
-mb_type .DV..
-qp .DV..
-mv .DV..
-dct_coeff .DV..
-skip .DV..
-startcode .DV..
-pts .DV..
-er .DV..
-mmco .DV..
-bugs .DV..
-vis_qp .DV..
-vis_mb_type .DV..
-vismv .DV.. visualize motion vectors
-pf .DV..
-bf .DV..
-bb .DV..
-mb_qmin E.V..
-mb_qmax E.V..
-cmp E.V.. full pel me compare function
-subcmp E.V.. sub pel me compare function
-mbcmp E.V.. macroblock compare function
-ildctcmp E.V.. interlaced dct compare function
-dia_size E.V..
-last_pred E.V..
-preme E.V..
-precmp E.V.. pre motion estimation compare function
-sad E.V..
-sse E.V..
-satd E.V..
-dct E.V..
-psnr E.V..
-bit E.V..
-rd E.V..
-zero E.V..
-vsad E.V..
-vsse E.V..
-nsse E.V..
-w53 E.V..
-w97 E.V..
-dctmax E.V..
-chroma E.V..
-pre_dia_size E.V..
-subq E.V.. sub pel motion estimation quality
-me_range E.V..
-ibias E.V..
-pbias E.V..
-coder E.V..
-vlc E.V.. variable length coder / huffman coder
-ac E.V.. arithmetic coder
-context E.V.. context model
-mbd E.V..
-simple E.V..
-bits E.V..
-rd E.V..
-sc_threshold E.V..
-lmin E.V.. min lagrange factor
-lmax E.V.. max lagrange factor
-nr E.V.. noise reduction
-rc_init_occupancy E.V..
-inter_threshold E.V..
-flags2 EDVA.
-antialias .DV..
-auto .DV..
-fastint .DV..
-int .DV..
-float .DV..
-qns E.V.. quantizer noise shaping
-thread_count EDV..
-dc E.V..
-nssew E.V.. nsse weight
-skip_top .DV..
-skip_bottom .DV..
-profile E.VA.
-unknown E.VA.
-level E.VA.
-unknown E.VA.
-lowres .DV..
-frame_skip_threshold E.V..
-frame_skip_factor E.V..
-frame_skip_exp E.V..
-skipcmp E.V.. frame skip compare function
-border_mask E.V..
-mb_lmin E.V..
-mb_lmax E.V..
-me_penalty_compensation E.V..
-bidir_refine E.V..
-brd_scale E.V..
-crf E.V..
-cqp E.V..
-keyint_min E.V..
-refs E.V..
-chromaoffset E.V..
-bframebias E.V..
-trellis E.VA.
-directpred E.V..
-bpyramid E.V..
-wpred E.V..
-mixed_refs E.V..
-8x8dct E.V..
-fastpskip E.V..
-aud E.V..
-brdo E.V..
-complexityblur E.V..
-deblockalpha E.V..
-deblockbeta E.V..
-partitions E.V..
-parti4x4 E.V..
-parti8x8 E.V..
-partp4x4 E.V..
-partp8x8 E.V..
-partb8x8 E.V..
-sc_factor E.V..
-mv0_threshold E.V..
-ivlc E.V.. intra vlc table
-b_sensitivity E.V..
-compression_level E.VA.
-use_lpc E..A.
-lpc_coeff_precision E..A.
-min_prediction_order E..A.
-max_prediction_order E..A.
-prediction_order_method E..A.
-min_partition_order E..A.
-max_partition_order E..A.


You can query the version by issuing the following command.

$ ffmpeg -version
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
ffmpeg SVN-rUNKNOWN
libavutil 3211264
libavcodec 3345152
libavformat 3278080


The next command is particularly useful, it provides an exhaustive list of codecs avalable, both video and audio. The fields preceeding each codec have the following meanings:
  • 'D' Decoding available
  • 'E' Encoding available
  • 'V/A/S' Video/audio/subtitle codec
  • 'S' Codec supports slices
  • 'D' Codec supports direct rendering
  • 'T' Codec can handle input truncated at random locations, not just frame boundaries

$ ffmpeg -formats
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
File formats:
E 3g2 3gp2 format
E 3gp 3gp format
D 4xm 4X Technologies format
D RoQ Id RoQ format
D aac ADTS AAC
DE ac3 raw ac3
E adts ADTS AAC
DE aiff Audio IFF
DE alaw pcm A law format
DE amr 3gpp amr file format
DE asf asf format
E asf_stream asf format
DE au SUN AU Format
DE audio_device audio grab and output
DE avi avi format
D avs avs format
E crc crc testing format
D daud D-Cinema audio format
D dc1394 dc1394 A/V grab
D dts raw dts
DE dv DV video format
D dv1394 dv1394 A/V grab
E dvd MPEG2 PS format (DVD VOB)
D ea Electronic Arts Multimedia Format
DE ffm ffm format
D film_cpk Sega FILM/CPK format
DE flac raw flac
D flic FLI/FLC/FLX animation format
DE flv flv format
E framecrc framecrc testing format
DE gif GIF Animation
DE gxf GXF format
DE h261 raw h261
DE h263 raw h263
DE h264 raw H264 video format
D idcin Id CIN format
DE image image sequence
DE image2 image2 sequence
DE image2pipe piped image2 sequence
DE imagepipe piped image sequence
D ingenient Ingenient MJPEG
D ipmovie Interplay MVE format
DE m4v raw MPEG4 video format
D matroska Matroska file format
DE mjpeg MJPEG video
D mm American Laser Games MM format
DE mmf mmf format
E mov mov format
D mov,mp4,m4a,3gp,3g2,mj2 QuickTime/MPEG4/Motion JPEG 2000 format
E mp2 MPEG audio layer 2
DE mp3 MPEG audio layer 3
E mp4 mp4 format
DE mpeg MPEG1 System format
E mpeg1video MPEG video
E mpeg2video MPEG2 video
DE mpegts MPEG2 transport stream format
D mpegvideo MPEG video
E mpjpeg Mime multipart JPEG format
DE mulaw pcm mu law format
D mxf MXF format
D nsv NullSoft Video format
E null null video format
DE nut nut format
D nuv NuppelVideo format
DE ogg Ogg Vorbis
E psp psp mp4 format
D psxstr Sony Playstation STR format
DE rawvideo raw video format
D redir Redirector format
DE rm rm format
E rtp RTP output format
D rtsp RTSP input format
DE s16be pcm signed 16 bit big endian format
DE s16le pcm signed 16 bit little endian format
DE s8 pcm signed 8 bit format
D sdp SDP
D shn raw shorten
D smk Smacker Video
D sol Sierra SOL Format
E svcd MPEG2 PS format (VOB)
DE swf Flash format
D tta true-audio
DE u16be pcm unsigned 16 bit big endian format
DE u16le pcm unsigned 16 bit little endian format
DE u8 pcm unsigned 8 bit format
E vcd MPEG1 System format (VCD)
D video4linux video grab
D video4linux2 video grab
D vmd Sierra VMD format
E vob MPEG2 PS format (VOB)
DE voc Creative Voice File format
DE wav wav format
D wc3movie Wing Commander III movie format
D wsaud Westwood Studios audio format
D wsvqa Westwood Studios VQA format
DE yuv4mpegpipe YUV4MPEG pipe format

Image formats (filename extensions, if any, follow):
DE gif gif

Codecs:
D V 4xm
D V D 8bps
D V D aasc
DEA ac3
DEA adpcm_4xm
DEA adpcm_adx
DEA adpcm_ct
DEA adpcm_ea
DEA adpcm_ima_dk3
DEA adpcm_ima_dk4
DEA adpcm_ima_qt
DEA adpcm_ima_smjpeg
DEA adpcm_ima_wav
DEA adpcm_ima_ws
DEA adpcm_ms
DEA adpcm_sbpro_2
DEA adpcm_sbpro_3
DEA adpcm_sbpro_4
DEA adpcm_swf
DEA adpcm_xa
DEA adpcm_yamaha
D A alac
DEV D asv1
DEV D asv2
D V D avs
D V bmp
D V D camstudio
D V D camtasia
D V D cavs
D V D cinepak
D V D cljr
D A cook
D V D cyuv
D A dts
DES dvbsub
DES dvdsub
DEV D dvvideo
DEV D ffv1
DEVSD ffvhuff
DEA flac
D V D flashsv
D V D flic
DEVSD flv
D V D fraps
DEA g726
DEA gsm
DEV D h261
DEVSDT h263
D VSD h263i
EV h263p
D V DT h264
DEVSD huffyuv
D V D idcinvideo
D V D indeo2
D V indeo3
D A interplay_dpcm
D V D interplayvideo
EV jpegls
D V kmvc
EV ljpeg
D V D loco
D A mace3
D A mace6
D V D mdec
DEV D mjpeg
D V D mjpegb
D V D mmvideo
DEA mp2
D A mp3
D A mp3adu
D A mp3on4
DEVSDT mpeg1video
DEVSDT mpeg2video
DEVSDT mpeg4
D VSDT mpegvideo
DEVSD msmpeg4
DEVSD msmpeg4v1
DEVSD msmpeg4v2
D V D msrle
D V D msvideo1
D V D mszh
D V D nuv
DEV pam
DEV pbm
DEA pcm_alaw
DEA pcm_mulaw
DEA pcm_s16be
DEA pcm_s16le
DEA pcm_s24be
DEA pcm_s24daud
DEA pcm_s24le
DEA pcm_s32be
DEA pcm_s32le
DEA pcm_s8
DEA pcm_u16be
DEA pcm_u16le
DEA pcm_u24be
DEA pcm_u24le
DEA pcm_u32be
DEA pcm_u32le
DEA pcm_u8
DEV pgm
DEV pgmyuv
DEV png
DEV ppm
D A qdm2
D V D qdraw
D V D qpeg
D V D qtrle
DEV rawvideo
D A real_144
D A real_288
D A roq_dpcm
D V D roqvideo
D V D rpza
DEV D rv10
DEV D rv20
D A shorten
D A smackaud
D V smackvid
D V D smc
DEV snow
D A sol_dpcm
DEA sonic
EA sonicls
D V D sp5x
DEV D svq1
D VSD svq3
D V theora
D V D truemotion1
D V D truemotion2
D A truespeech
D A tta
D V D ultimotion
D V vc1
D V D vcr1
D A vmdaudio
D V D vmdvideo
DEA vorbis
D V vp3
D V D vqavideo
D A wmav1
D A wmav2
DEVSD wmv1
DEVSD wmv2
D V wmv3
D V D wnv1
D A ws_snd1
D A xan_dpcm
D V D xan_wc3
D V D xl
DEV D zlib
D V zmbv

Supported file protocols:
file: pipe: udp: rtp: tcp: http:
Frame size, frame rate abbreviations:
ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif
Motion estimation methods:
zero(fastest) full(slowest) log phods epzs(default) x1 hex umh iter

Note, the names of encoders and decoders dont always match, so there are
several cases where the above table shows encoder only or decoder only entries
even though both encoding and decoding are supported for example, the h263
decoder corresponds to the h263 and h263p encoders, for file formats its even
worse


Enough with the preliminaries, to begin using the utility you need to begin by specifying the input stream which can take the form of video file, a video hardware stream, or a series of images. The -i argument specifier specifies the input to be manipulated.

If you only specify an input file with no output file FFmpeg will display the input source information, for example:

$ ffmpeg -i ./ffmpeg/video0.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from './ffmpeg/video0.avi':
Duration: 00:01:17.1, start: 0.000000, bitrate: 14082 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s

Must supply at least one output file


Note that the input stream #0 shows the video and audio specifics for the input. You'll later learn how specifying an output file you'll be enabled to manipulate the input source to the desired output format.

Let's finish off this post by converting a Mpeg4 encoded video in an AVI container to an encoded video to a MPG container.

$ ffmpeg -i ffmpeg/video0.avi /tmp/video0.mpg
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

Seems that stream 0 comes from film source: 30000.00 (30000/1) -> 29.97 (30000/1001)
Input #0, avi, from 'ffmpeg/video0.avi':
Duration: 00:01:17.1, start: 0.000000, bitrate: 14082 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 29.97 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Output #0, mpeg, to '/tmp/video0.mpg':
Stream #0.0: Video: mpeg1video, yuv420p, 720x480, q=2-31, 200 kb/s, 29.97 fps(c)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 2313 q=31.0 Lsize= 7584kB time=77.0 bitrate= 806.7kbits/s
video:6920kB audio:602kB global headers:0kB muxing overhead 0.826762%