stillhq.com : Mikal, a geek from Canberra living in Silicon Valley http://www.stillhq.com The life, times, travel and software of Michael Still en Copyright (c) Michael Still 2000 - 2006 blosxom simplerss20 v20050208hh 180 http://blogs.law.harvard.edu/tech/rss The new way of converting JPEGs to MPEGs /jpeg2mpeg Mon, 20 Jun 2005 17:20:00 GMT I wrote the <a href="/jpeg2mpeg/000001.html">JPEG to MPEG howto a while ago</a>, and used the best tools that I could find at the time. It was a complicated, evil process, but people still email me a couple of times a month and thank me for it. I think they'll like this way even more. <br/><br/> For my PhD, I'm taking large numbers of images and displaying them one after another on a monitor so that I can capture the images with a webcam. The reason is a little convoluted, so let's settle for I'm trying to see what sort of image distortion the webcam will impose. I figured that the best way to do this was to simply have a MPEG2 movie that was the images, play it on the machine, and then point the webcam at the monitor. At about this time in a twist of wonderful fate I discovered I could do this in a simple command line with ImageMagick. Let's see how (all of these instructions are based on Debian unstable, but should work anywhere): <br/><br/> <b>Install ImageMagick</b> <br/><br/> <ul><pre> apt-get install imagemagick </pre></ul> <br/><br/> <b>Install mpeg2vidcodec</b> <br/><br/> This isn't packaged for Debian, but I've put a request for package bug in. Do this: <br/><br/> <ul><pre> wget ftp://ftp.mpegtv.com/pub/mpeg/mssg/mpeg2vidcodec_v12.tar.gz tar xvzf mpeg2vidcodec_v12.tar.gz cd mpeg2 make cd src/mpeg2dec cp mpeg2decode /usr/local/bin cd ../mpeg2enc cp mpeg2encode /usr/local/bin </pre></ul> <br/><br/> <b>Do the thing</b> <br/><br/> So, now we can do the thing. In this instance we have a bunch of TIFF files we want to turn into an MPEG2 video. <br/><br/> <ul><pre> convert *.tif foobar.mpg </pre></ul> <br/><br/> And we're done. Nice, isn't it? <br/><br/><i>Technorati tags for this post: <a href="http://technorati.com/tag/jpeg2mpeg" rel="tag">jpeg2mpeg</a> <a href="http://technorati.com/tag/jpeg" rel="tag">jpeg</a> <a href="http://technorati.com/tag/mpeg" rel="tag">mpeg</a> <a href="http://technorati.com/tag/movie" rel="tag">movie</a> <a href="http://technorati.com/tag/convert" rel="tag">convert</a> <a href="http://technorati.com/tag/imagemagick" rel="tag">imagemagick</a> <a href="http://technorati.com/tag/phd" rel="tag">phd</a> <a href="http://technorati.com/tag/tutorial" rel="tag">tutorial</a> <a href="http://technorati.com/tag/howto" rel="tag">howto</a> <a href="http://technorati.com/tag/opensource" rel="tag">opensource</a> <a href="http://technorati.com/tag/linux" rel="tag">linux</a> <a href="http://technorati.com/tag/video" rel="tag">video</a> </i> <a href="http://www.stillhq.com/jpeg2mpeg/000002.commentform.html">Comment</a> http://www.stillhq.com/jpeg2mpeg/000002.html http://www.stillhq.com/jpeg2mpeg/000002.html Howto /jpeg2mpeg Wed, 11 Sep 2002 07:00:00 GMT <div CLASS="ARTICLE" ><div CLASS="TITLEPAGE" ><h1 CLASS="TITLE" ><a NAME="AEN1" >JPEG to MPEG conversion howto</a ></h1 ><hr WIDTH="75%" ALIGN="CENTER" COLOR="#000000" SIZE="1"></div ><div CLASS="TOC" ><dl ><dt ><b >Table of Contents</b ></dt ><dt ><a HREF="#AEN3" >Abstract</a ></dt ><dt ><a HREF="#AEN7" >MPEG tools</a ></dt ><dt ><a HREF="#AEN10" >Dependancies</a ></dt ><dt ><a HREF="#AEN67" >Encoding the JPEGS into the MPEG</a ></dt ></dl ></div ><div CLASS="SECT1" ><h1 CLASS="SECT1" ><a NAME="AEN3" >Abstract</a ></h1 ><p >Recently, I went to a conference and was keen enough to setup a webcam. Now I have 27,000 JPEG images, which I want to turn into a simple MPEG movie. This document details the process I went through to make this happen...</p ><p >This was all done on a pretty vanilla Redhat 7.1 box, for those who care about such things.</p ></div ><div CLASS="SECT1" ><hr><h1 CLASS="SECT1" ><a NAME="AEN7" >MPEG tools</a ></h1 ><p >The project I found which did the conversion is called MJPEG tools. The URL for this project is http://mjpeg.sourceforge.net. There were lots of dependancies, which we should talk about first...</p ></div ><div CLASS="SECT1" ><hr><h1 CLASS="SECT1" ><a NAME="AEN10" >Dependancies</a ></h1 ><div CLASS="SECT2" ><h2 CLASS="SECT2" ><a NAME="AEN12" >libavifile</a ></h2 ><p >This library can be found at http://avifile.sourceforge.net. It is needed by MJPEG tools to be able to handle AVI files. The version I used was 0.7-0.7.15. It follows the standard autotools install process:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >./configure make make install</pre ></td ></tr ></table ></div ><div CLASS="SECT2" ><hr><h2 CLASS="SECT2" ><a NAME="AEN16" >libsdl</a ></h2 ><p ><span CLASS="QUOTE" >"Simple DirectMedia Layer is a cross-platform multimedia library designed to provide fast access to the graphics framebuffer and audio device. It is used by MPEG playback software, emulators, and many popular games, including the award winning Linux port of "Civilization: Call To Power." Simple DirectMedia Layer supports Linux, Win32, BeOS, MacOS, Solaris, IRIX, and FreeBSD."</span > -- http://www.libsdl.org/index.php</p ><p >libsdl can be found at http://www.libsdl.org, and is needed for some of the MJPEG playback routines. I used version 1.2.4. Again, installing is done by simply:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >./configure make make install</pre ></td ></tr ></table ></div ><div CLASS="SECT2" ><hr><h2 CLASS="SECT2" ><a NAME="AEN22" >nasm</a ></h2 ><p >NASM is an assembler, and the authors are none to modest. The web page is http://sourceforge.net/projects/nasm and to quote from that page:</p ><p ><span CLASS="QUOTE" >"This is NASM - the famous Netwide Assembler. Back at SourceForge and in intensive development!"</span ></p ><p >It can't be that famous, I've never heard of it before.</p ><p >An explaination of where NASM came from can be found in the documentation:</p ><a NAME="AEN29" ></a ><table BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0" CLASS="BLOCKQUOTE" ><tr ><td WIDTH="10%" VALIGN="TOP" >&nbsp;</td ><td WIDTH="80%" VALIGN="TOP" ><p >The Netwide Assembler grew out of an idea on comp.lang.asm.x86 (or possibly alt.lang.asm - I forget which), which was essentially that there didn't seem to be a good free x86-series assembler around, and that maybe someone ought to write one.</p ><p ></p ><ul ><li ><p >a86 is good, but not free, and in particular you don't get any 32-bit capability until you pay. It's DOS only, too.</p ></li ><li ><p >gas is free, and ports over DOS and Unix, but it's not very good, since it's designed to be a back end to gcc, which always feeds it correct code. So its error checking is minimal. Also, its syntax is horrible, from the point of view of anyone trying to actually write anything in it. Plus you can't write 16-bit code in it (properly).</p ></li ><li ><p >as86 is Minix- and Linux-specific, and (my version at least) doesn't seem to have much (or any) documentation.</p ></li ><li ><p >MASM isn't very good, and it's expensive, and it runs only under DOS.</p ></li ><li ><p >TASM is better, but still strives for MASM compatibility, which means millions of directives and tons of red tape. And its syntax is essentially MASM's, with the contradictions and quirks that entails (although it sorts out some of those by means of Ideal mode). It's expensive too. And it's DOS-only.</p ></li ></ul ><p >So here, for your coding pleasure, is NASM. At present it's still in prototype stage - we don't promise that it can outperform any of these assemblers. But please, please send us bug reports, fixes, helpful information, and anything else you can get your hands on (and thanks to the many people who've done this already! You all know who you are), and we'll improve it out of all recognition. Again.</p ></td ><td WIDTH="10%" VALIGN="TOP" >&nbsp;</td ></tr ><tr ><td COLSPAN="2" ALIGN="RIGHT" VALIGN="TOP" >--<span CLASS="ATTRIBUTION" >http://home.attbi.com/~fbkotler/nasmdoc1.html#section-1.1</span ></td ><td WIDTH="10%" >&nbsp;</td ></tr ></table ><p >Install it by doing the autotools thing once more. Note that the make install step is broken, and that I had to do this to get it to install:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >mkdir bin mkdir man mkdir man/man1 make install cp bin/nasm /usr/local/bin/ cp man/man1/n* /usr/local/man/man1/</pre ></td ></tr ></table ></div ><div CLASS="SECT2" ><hr><h2 CLASS="SECT2" ><a NAME="AEN46" >jpeg-mmx</a ></h2 ><p >We'll also need the MJPEG people's MMX JPEG library. I am not sure how this differs from the standard JPEG library, which also seems to be an option here... I downloaded version 0.1.4, and did the autotools thing.</p ><p >For some reason they have disabled make install. I did:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >[root@localhost jpeg-mmx-0.1.4]# make install Make install has been disabled If you really want to install libjpeg-mmx, please use make install_real [root@localhost jpeg-mmx-0.1.4]# make install_real /usr/bin/install -c -m 644 jconfig.h /usr/local/include/jconfig.h /usr/bin/install -c -m 644 ./jpeglib.h /usr/local/include/jpeglib.h /usr/bin/install -c -m 644 ./jmorecfg.h /usr/local/include/jmorecfg.h /usr/bin/install -c -m 644 ./jerror.h /usr/local/include/jerror.h /usr/bin/install -c -m 644 ./jinclude.h /usr/local/include/jinclude.h /usr/bin/install -c -m 644 libjpeg-mmx.a /usr/local/lib/libjpeg-mmx.a [root@localhost jpeg-mmx-0.1.4]# </pre ></td ></tr ></table ><p >And annoyingly, I also had to manually copy a file:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >cp jpegint.h /usr/local/include/</pre ></td ></tr ></table ></div ><div CLASS="SECT2" ><hr><h2 CLASS="SECT2" ><a NAME="AEN53" >movtar</a ></h2 ><p >movtar is actaully written by the MJPEG people. You can download it from http://download.sourceforge.net/mjpeg/. I used the 1.3.0 release. The install was auttooled once more. I am sure by now I don't have to explain how to do that...</p ></div ><div CLASS="SECT2" ><hr><h2 CLASS="SECT2" ><a NAME="AEN56" >Compiling MJPEG tools itself</a ></h2 ><p >I downloaded version 1.6.0 from the sourceforge website. Yet again, the install process was:</p ><p >This wouldn't make out of the box:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >g++ -g -O2 -o .libs/divxdec divxdec.o lav_common.o -Wl,-rpath -Wl,/usr/local/lib -L/root/mjpegtools-1.6.0/utils -lmjpegutils -L/usr/local/lib /usr/local/lib/libaviplay.so -lz -L/usr/X11R6/lib -lSM -lICE -lXxf86dga -lXxf86vm -lXi -lXft -lXv -lXext -lX11 -lpthread -lnsl -ldl -lm ./.libs/liblavfile.so -L/usr/lib /usr/lib/libglib.so -lmovtar -L/root/mjpegtools-1.6.0/../jpeg-mmx-0.1.4 ./.libs/liblavplay.so ./.libs/liblavjpeg.so -ljpeg-mmx -Wl,--rpath -Wl,/usr/local/lib ./.libs/liblavplay.so: undefined reference to `SDL_Quit' ./.libs/liblavplay.so: undefined reference to `SDL_WM_SetCaption' ./.libs/liblavplay.so: undefined reference to `SDL_CreateYUVOverlay' ./.libs/liblavplay.so: undefined reference to `SDL_LockYUVOverlay' ./.libs/liblavplay.so: undefined reference to `SDL_EventState' ./.libs/liblavplay.so: undefined reference to `SDL_UnlockSurface' ./.libs/liblavplay.so: undefined reference to `SDL_LockSurface' ./.libs/liblavplay.so: undefined reference to `SDL_DisplayYUVOverlay' ./.libs/liblavplay.so: undefined reference to `SDL_UpdateRect' ./.libs/liblavplay.so: undefined reference to `SDL_Init' ./.libs/liblavplay.so: undefined reference to `SDL_GetError' ./.libs/liblavplay.so: undefined reference to `SDL_UnlockYUVOverlay' ./.libs/liblavplay.so: undefined reference to `SDL_FreeYUVOverlay' ./.libs/liblavplay.so: undefined reference to `SDL_SetVideoMode' collect2: ld returned 1 exit status</pre ></td ></tr ></table ><p >Until I had applied this <a href="/jpeg2mpeg/make-compile.diff">patch</a>.</p ><p >Then we can go ahead and make the project:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >./configure make make install</pre ></td ></tr ></table ><p >For those who are interested, my build configuration at the end of the configure script looked like:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" > MJPEG tools 1.6.0 build configuration : - X86 Optimizations: - MMX/3DNow!/SSE enabled : true - cmov support enabled : true *********************************************************************** * NOTE: * * The resultant binaries will ***NOT*** run on a K6 or Pentium CPU * *********************************************************************** - video4linux recording/playback: true - software MJPEG playback : true - movtar playback/recording : true - Quicktime playback/recording : false - AVI MJPEG playback/recording : true (always) - libDV (digital video) support : false - AVIFILE divx encoding support : true - Gtk+ support for glav : true - glibc support for &#62;2GB files : true</pre ></td ></tr ></table ></div ></div ><div CLASS="SECT1" ><hr><h1 CLASS="SECT1" ><a NAME="AEN67" >Encoding the JPEGS into the MPEG</a ></h1 ><p >Finally, we can use MJPEG tools to convert the JPEGs into a MPEG stream.</p ><p ><span CLASS="QUOTE" >"You can use jpeg2yuv to create a yuv stream from separate JPEG images. This stream is sent to stdout, so that it can either be saved into a file, encoded directly to a mpeg video using mpeg2enc or used for anything else."</span ></p ><p ><span CLASS="QUOTE" >"Saving an yuv stream can be done like this: <b CLASS="COMMAND" >jpeg2yuv -f 25 -j image%05d.jpg &#62; result.yuv</b >"</span ></p ><p ><span CLASS="QUOTE" >"Creates the file result.yuv containing the yuv video data with 25 FPS. The -f option is used to set the frame rate. Note that image%05d.jpg means that the jpeg files are named image00000.jpg, image00001.jpg and so on. (05 means five digits, 04 means four digits, etc.)"</span ></p ><p ><span CLASS="QUOTE" >"If you want to encode a mpeg video directly from jpeg images without saving a separate video file type: <b CLASS="COMMAND" >jpeg2yuv -f 25 -j image%05d.jpg | mpeg2enc -o mpegfile.m1v</b >"</span > -- https://sourceforge.net/docman/display_doc.php?docid=3456&#38;group_id=5776#Images</p ><p >Note that this documentation is wrong, and you also need to include an interlacing option...</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >jpeg2yuv -f 25 -j frame-%05d.jpg -I p | mpeg2enc -o mpegfile.m1v</pre ></td ></tr ></table ><p >The frames also have to count from 00000 in this example. I used the following little script to convert to the required naming format:</p ><table BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><tr ><td ><pre CLASS="PROGRAMLISTING" >count=0 for item in `find . -type f` do mv $item frame-`printf "%05d" $count`.jpg count=$(( $count + 1 )) done</pre ></td ></tr ></table ><p >Note that the conversion is also quite slow, I walked away and came back later.</p ></div ></div > <a href="http://www.stillhq.com/jpeg2mpeg/000001.commentform.html">Comment</a> http://www.stillhq.com/jpeg2mpeg/000001.html http://www.stillhq.com/jpeg2mpeg/000001.html