   \input texinfo

Frame rate conversion
=====================

   Ever needed to convert the framerate from PAL to NTSC or the other
direction around ? Or something much simpler like converting the
framerate from 24FPS to 24000:1001 for conversation from a film frame
rate to a valid NTSC frame rate.

   Than `yuvfps' is your program. It can lower the framerate by dropping
frames, or create a higher framerate by replicating frames. If you have
a wrong framerate in the header you can only change the header of the
YUV stream and not modify the stream.

   Because the frames are only replicated (copied) you should denoise
first and then change the framerate and scale at als last step. If you
have a interlaced source you should also deinterlace before changeing
the framerate. If you create a higher frame rate it is very likely that
you will have weird flickers when you play it back. If you convert PAL
to NTSC (30000:1001 FPS about 29,97 FPS) the frame rate will lower by
about the factor 480/576 (NTSC lines / PAL lines).  If you lower the
frame rate from PAL to NTSC (at 24000:1001) or NTSC FILM (24FPS) the
bitrate will be about (480 Lines * 24 FPS) / (576 Lines * 25FPS).  If
you change the frame rate before denoising the yuvdenoise will have
problems finding the noise across the frames, so the needed bandwith
will slightly increase.

   Example

   `> lav2yuv video.eli | yuvfps -r 30000:1001 | yuvscaler -O SVCD |
mpeg2enc -f 4 -o video_ntsc_svcd.m2v'

   This is a example to convert the source video to a NTSC video
running at 30000:1001 FPS (or about 29,97FPS) at SVCD size.

   Example

   `> lav2yuv video.eli | yuvdenoise -F | yuvfps -r 24000:1001 |
yuvscaler -O SIZE_720x480 | mpeg2enc -f 3 -b 4000 -q 7 -o
video_ntsc.m2v'

   This example shows how you should use the tools. Denoise first and
than change the framerate and in the last step change the image size.

   It can happen that yuvscaler or mpeg2enc do not detect the TV norm
correct. If that happens you have to add the norm option `-n n/p/s' to
the program that chooses the wrong norm.

   If you know that the header tells the wrong framerate, you can
simply change the framerate of the yuv header this way:

   `> lav2yuv video.eli | yuvfps -r 25:1 -c | mpeg2enc -f 3 -b 4000 -q
7 -o video_pal.m2v'

   You need the `-c' option. To tell yuvfps that it only should change
the header of the stream. With the `-r 25:1' you tell yuvfps the frame
rate it should write into the header. In your example the PAL frame
rate of 25 FPS. You always have to use the fractional form.

   If you know that the header is wrong, and you need a different output
bitrate you can do this in a single step:

   `> lav2yuv video.eli | yuvfps -s 24:1 -r 25:1 | mpeg2enc -o
video.m1v'

Transcoding of existing MPEG-2
******************************

   For transcoding existing MPEG-2 streams from digital TV cards or DVD
a lower data-rate than for broadcast will give good results.  Standard
VCD 1152 kbps typically works just fine for MPEG1. The difference is in
the Signal/Noise ratio of the original. The noise in the analog stuff
makes it much harder to compress.

   One other very good guide that helps you transcoding videos can be
found at: http://www.bunkus.org/dvdripping4linux/index.html

   You will also need to manually adjust the audio delay offset
relative to video when multiplexing. Very often around 150ms delay
seems to do the trick.

   You have to download the ac3dec and mpeg2dec packages. You can find
them at mjpeg homepage ( http://sourceforge.net/projects/mjpeg ).  You
also need sox and toolame.

   In the scripts directory there is a `mpegtranscode' script that does
most of the work.

   So transcoding looks like this:

   `> mjpegtranscode -V -o vcd_stream mpeg2src.mpg'

`-V'
     set's the options so that a VCD compatible stream is generated

`-o vcd_stream'
     a vcd_stream.m1v (video) and vcd_stream.mp2 (audio) is created

`mpeg2src.mpg'
     specifies the source stream

   The script prints also something like this:

   `> SYNC 234 mSec'

   You will need to adjust the audio/video startup delays when
multiplexing to ensure audio and video are synchronized.  The exact
delay (in milliseconds) that you need to pass to mplex to synchronize
audio and video using the "-v"" is printed by the extract_ac3 tool
labeled "SYNC" when run with the "s" flag. This is the value th
mjpegtranscode script prints out after the `SYNC' word.

   Then you need to multiplex them like this:

   `> mplex -f 1 -O 234 vcd_stream.mp2 vcd_stream.m1v -o lowrate.mpg'

`-f 1'
     Mux format is set to VCD

`-O 234'
     Video timestamp offset in mSec, generated by the mjpegtranscoding
     script, there negative values are allowed

`vcd_stream.mp2 & vcd_stream.m1v'
     generated files by the script

`lowrate.mpg'
     the VCD compatible output stream

   Here we have a SVCD (MPEG-2 video) example:

   `> mjpegtranscode -S -o svcd_stream mpeg2src.mpg'

   You have to multiplex it with:

   `> mplex -f 4 -O 234 svcd_stream.mp2 svcd_stream.m2v -o lowrate.mpg'

   `Problem:' There is sometimes a problem with NTSC and VCD playback
because movies may be recoded with 3:2 pulldown NTSC with 60
fields/sec. mpeg2dec is designed for playback on computers and
generates the original 24frames/sec bitrate. If you encode the video
now 30frames/sec video is created. This video is now much too short for
the encoded audio.

   The transcoding can be made to work but it must be done manually:

   `> cat mpeg2src.mpg | mpeg2dec -s -o YUVs | mpeg2enc -I 0 -f 4 -q 9
-V 230 -p -P -o svcd_stream.m2v'

   The -p tells mpeg2enc to generate header flags for 3:2 pull down of
24fps movie. It may also work if you do not add the -p flag.  You do
not need the -p flag when transcoding to VCD format because it is not
supported in mpeg1.

If you want to do every step on your own it will look something like this
=========================================================================

   Extracting Audio:

   `> cat test2.mpg | extract_ac3 - -s | ac3dec -o wav -p sound.wav
2>/dev/null'

   One of the first lines showed contains the label "SYNC" you have to
use this time later when multiplexing. The 2>/dev/null redirects the
output of ac3dec to /dev/null.  In the next step you generate the mpeg
audio file:

   `> cat sound.wav | mp2enc -V -v 2 -o audio.mp2'

`-V'
     forces VCD format, the sampling rate is converted to 44.1kHz from
     48kHz

`-v 2'
     unnecessary but if you use it mp2enc tells you how many seconds of
     the audio file are already encoded.

`-o'
     Specifies the output file.

   cat test2.mpg | extract_ac3 - -s | ac3dec -o wav | sox -t wav
/dev/stdin -t wav -r 44100 /dev/stdout | toolame -p 2 -b 224 /dev/stdin
audio.mp2

   One of the first lines again output contains the label "SYNC".  You
have to use this time (referred to as "SYNC_value" below) when doing the
multiplexing.

   For VCD creation use:

   `> cat test2.mpg " mpeg2dec -s -o YUVh " mpeg2enc -s -o
video_vcd.m1v'

`'
     mpeg2dec:

`-s'
     tells mpeg2dec to use program stream demultiplexer

`-o YUVh'
     the output size of the extracted frames.

   There are other output modes, try "mpeg2dec -help" but the most
important here are:

`YUV'
     is the full image size, unscaled

`YUVs'
     is SVCD size, it can only scale down to 2/3 of the original size

`YUVh'
     is VCD size, or about the half of the original size

   Mplex with:

   `> mplex -f 1 -O SYNC_value audio.mp2 video_vcd.m1v -o
vcd_stream.mpg'

`-f 1'
     generates an VCD stream

`-O SYNC_value'
     the value mentioned above

   For SVCD creation use:

   `> cat test2.mpg | mpeg2dec -s -o YUVs | mpeg2enc -f 4 -q 9 -V 230
-o video_svcd.mpg'

`-q 9'
     Quality factor for the stream (VBR stream) (default q: 12)

`-V 230'
     Target video buffer size in KB

`-o'
     Output file

   Mplex with:

   `> mplex -f 4 -b 230 audio.mp2 video_svcd -o svcd_stream.mpg'

`-f 4'
     generate an SVCD stream

`-b 200'
     Specify the video buffer size by the playback device.

   For other video output formats this might work:

   `> cat test2.mpg | mpeg2dec -s -o YUV | yuvscaler -O SIZE_320x200 -O
NOT_INTERLACED | mpeg2enc -o strange_video.m1v'

   If you want to edit mpeg streams, this also works, but in a slightly
different way. For demultiplexing you can use bbdmux, from the bbtools
package. Splits out either video or audio very cleanly.  You can't get
it any more from the homepage from Brent Beyler, it can still be found
when you search for it using that keywords " bbtools linux -suse
-blackbox". Currenty it can be found at: http://www.nop.org/inkling/

   First run:

   `> bbdmux myvideo.mpg'

   You should get something like this:

   Found stream id 0xE0 = Video Stream 0 Found stream id 0xC0 = MPEG
Audio Stream 0 Found stream id 0xBE = Padding Stream

   Extract audio with:

   `> bbdmux myvideo.mpg 0xC0 audio.mp1'

   Convert it to wav:

   `> mpg123 -w audio.wav audio.m1v'

   Extract video with:

   `> bbdmux myvideo.mpg 0xE0 video.m1v'

   Converting video to an mjpeg avi stream:

   `> cat video.m1v | mpeg2dec -o YUV | yuv2lav -f a -o test.avi'

   Then adding the sound to the avi:

   `> lavaddwav test.avi audio.wav final.avi'

   If the source video has already the size of the target video use -o
YUV. Using YUVh makes the video the half size!  The rest can be done
just like editing and encoding other streams.  If you have videos with
ac3 sound you only have to adapt the commands above.

   Extracting Audio:

   `> cat test2.mpg | extract_ac3 - -s | ac3dec -o wav 2>dev/null
>sound.wav'

   Extract video:

   `> cat test2.mpg | mpeg2dec -s -o YUVh | yuv2lav -f a -q 85 -o
test.avi'

   Adding the sound:

   `> lavaddwav test.avi sound.wav fullvideo.avi'

   `NOTE:'You need much disk space. 1GB of video has a size of about 2GB
at SVCD format and of course disk space is needed for some temp files.
Converting the video to mjpeg also takes some time.  On my Athlon 500 I
never get more than 6-7 Frames a second.  You loose quality each time
you convert a stream into an other format!

Trading Quality/Speed
*********************

   If absolute quality is your objective a modest improvement can be
achieved using the -4 and -2 flags.  These control how ruthlessly
mpeg2enc discards bad looking matches between sections of adjacent
frames during the early stages of the search when it is working with
4*4 and 2*2 clusters of pixels rather than individual pixels. Setting
-4 1 -2 1 maximizes quality. -4 4 -2 4 maximizes speed. Note that
because the statistical criteria mpeg2enc uses for discarding bad
looking matches are usually fairly reliable the increase/decrease in
quality is modest (but noticeable).

   Reducing the radius of the search for matching sections of images
also increases speed. However due to the way the search algorithm works
the search radius is in effect rounded to the nearest multiple of 8.
Furthermore, on modern CPU's the speed gained by reducing the radius
below 16 is not large enough to make the marked quality reduction
worthwhile for most applications.

Creating streams to be played from disk using Software players
==============================================================

   Usually MPEG player software is much more flexible than the hardware
built into DVD and VCD players. This flexibility allows for
significantly better compression to be achieved for the same quality.
The trick is to generate video streams that use big video buffers
(500KB or more) and variable bitrate encoding (the -f, -q flag to
mpeg2enc). Software players will often also correctly play back the
more efficient MPEG layer 3 (yes, "MP3" audio format.  A good MP3
encoder like lame will produce results comparable to layer 2 at 224Kbps
at 128Kbps or 160Kbps.

SMP and distributed Encoding
****************************

   The degree to which mpeg2enc tries to split work between concurrently
executing threads is controlled by the -M or -multi-thread [0..32]
option. This optimizes mpeg2enc for the specified number of CPUs. By
default (-M 1), mpeg2enc runs with just a little multi-threading:
reading of frames happens concurrently with compression. This is done
to allow encoding pipelines that are split across several machines (see
below) to work efficiently without the need for special buffering
programs.  If you are encoding on a single-CPU machine where RAM is
tight you may find turning off multithreading altogether by setting -M
0 works slightly more efficiently.

   For SMP machines with two ore more processors you can speed up
mpeg2enc by setting the number of concurrently executing encoding
threads's you wish to utilize (e.g. -M 2). Setting -M 2 or -M 3 on a
2-way machine should allow you to speed up encoding by around 80%.
Values above 3 are accepted but have very little effect even on 4 cpu
systems.

   If you have a real fast SMP machine (currently 1.Aug.03) like a dual
Athlon MP 2600 or something similar the -M 2 and the filtering might not
keep both (or more)  CPU's busy. The use of the buffer or bfr program
with a 10-20MB buffer helps to keep both CPUs busy.

   Obviously if your encoding pipeline contains several filtering stages
it is likely that you can keep two or more CPU's busy simultaneously
even without using -M. Denoising using yuvdenoise or yuvmedianfilter is
particular demanding and uses almost as much processing power as MPEG
encoding.

   It you more than one computer you can also split the encoding
pipeline between computers using the standard 'rsh' or 'rcmd' remote
shell execution commands. For example, if you have two computers:

   `> rsh machine1 lav2yuv "mycapture.eli | yuvscaler -O SVCD |
yuvdenoise" | mpeg2enc -f 4 -o mycapture.m2vi'

   Here the computer where you execute the command is doing the MPEG
encoding and "machine1" is the machine that is decoding scaling and
denoising the captured video.

   Obviously, for this to work "machine1" has to be able to access the
video and the computer where the command is executed has to have space
for the encoded video. In practice, it is usually well worth setting up
network file-storage using "NFS" or other packages if you are going to
do stuff like this.  If you have three computers you can take this a
stage further, one computer could do the decoding and scaling, the next
could do denoising and the third could do MPEG encoding:

   `> rsh machine1 "lav2yuv mycapture.eli | yuvscaler -O SVCD" |
yuvdenoise | rsh machine3 mpeg2enc -f 4 -o mycapture.m2v'

   `NOTE:'How the remote command executions are set up so that the data
is sent direct from the machine that produces it to the machine that
consumes it.

   In practice for this to be worthwhile the network you are using must
be fast enough to avoid becoming a bottleneck. For Pentium-III class
machines or above you will need a 100Mbps Ethernet.

   For really fast machines a switched 100MBps Ethernet (or better!) may
be needed.Setting up the rshd ("Remote Shell Daemon" needed for rsh to
do its work and configuring "rsh" is beyond the scope of this document,
but its a standard package and should be easily installed and activated
on any Linux or BSD distribution.

   Be aware that this is potentially a security issue so use with care
on machines that are visible to outside networks!

Interoperability
****************

   Quicktime files capturing using lavrec can be edited using
Broadcast2000.  But Broadcast2000 is not available any more on
heroinewarrior.  mjpeg AVI files captured using the streamer tool from
the xawtv package can be edited and compressed and played back using
software.  Hardware playback is not possible for such files due to
limitations in the Zoran hardware currently supported. Videos recorded
with NuppelVideo can also be processed with the mjpeg tools.

   If you have a Macintosh (MAC) and want to use the mjpeg tools look
there: http://www.sjoki.uta.fi/~shmhav/SVCD_on_a_Macintosh.txt and
http://homepage.mac.com/rnc/

   MPEG files produced using the tools are know to play back correctly
on:

   * dxr2 (hardware decoder card)

   * xine http://xine.sourceforge.net/

   * oms http://www.linuxvideo.org/

   * dvdview http://rachmaninoff.informatik.uni-mannheim.de/dvdview/

   * xmovie http://heroinewarrior.com/xmovie.php3

   * mplayer http://mplayer.sourceforge.net/

   * vlc http://www.videolan.org/

   * MPEG1 only: mtv http://www.mpegtv.com/

   * MPEG1 only: gtv
     http://packages.debian.org/stable/graphics/smpeg-gtv.html

   * MS Media player version 6 and 7

   * SW DVD Player

   To find out what you HW-player (most of the time DVD player) can do
take a look at: http://www.vcdhelp.com

   It seems that the MS Media player likes MPEG-1 streams more if you
have used -f 1 when multiplexing.

   If you have any problems or suggestions feel free to mail me
(Bernhard Praschinger): waldviertler@users.sourceforge.net There is a
lot of stuff added from the HINTS which Andrew Stevens (
andrew.stevens@nexgo.de ) created. Wolfgang Goeller checked the
document for bugs and spelling mistakes.

   And to the people who have helped me with program descriptions and
hints, `thanks'