[MPlayer-users] Re: Tools for mpeg* to DVD
Tobias Diedrich
ranma at gmx.at
Sat Dec 20 00:59:01 CET 2003
Andrew Stevens wrote:
> Unless I'm very much mistaken ffmpeg encodes MPEG-2 with interlaced support
> and B frames off. These are on by default in mpeg2enc. If you turn them off
ffmpeg does support b frames with mpeg2. Interlaced should kinda work if
you turn on interlaced idct, but I did not have to deal with interlaced
material yet, so I didn't try it.
I use the following script to encode DVD compliant MPEG2 that works in
my hardware player (Pioneer DV-535):
---------- transcode_to_mpeg2.sh -----------
#!/bin/bash
#
# 2003 (C) by Tobias Diedrich <ranma at gmx.at>
#
# Licensed under GNU GPL.
#
PATH=/bin:/usr/bin:/usr/local/bin
#tmpdir="${TMPDIR-/tmp}/`basename "$0"`-`basename "$1"`"
tmpdir="${TMPDIR-/tmp}" # where the files go
workdir="$tmpdir/`basename "$0"`-`basename "$1"`-$$" # for stream.yuv
wd=`pwd`
if [ "`dirname "$1" | awk '{ print substr($0, 1, 1) }'`" != "/" ]; then
source="$wd/$1"
else
source="$1"
fi
tmpavi="$tmpdir/`basename "$1"`"
tmpbase="${tmpavi%avi}"
tmpmpg="${tmpbase}tmp"
tmpmp2="${tmpbase}mp2"
tmpac3="${tmpbase}ac3"
tmpm2v="${tmpbase}m2v"
tmpraw="${tmpbase}raw"
tmpwav="${tmpbase}wav"
tmplog="${tmpbase}log"
tmpyuv="${tmpbase}yuv"
result="${tmpbase}mpg"
if [ "$2" != "" ]; then
if [ "`dirname "$2" | awk '{ print substr($0, 1, 1) }'`" != "/" ]; then
result="$wd/$2"
else
result="$2"
fi
fi
test -d "$tmpdir" || mkdir "$tmpdir"
test -d "$workdir" || mkdir "$workdir"
pushd "$workdir"
eval `midentify "$source"`
if [ "$ID_VIDEO_ASPECT" = "0.0000" ]; then
aspect=`bc <<EOF
scale=0
100*${ID_VIDEO_WIDTH}/${ID_VIDEO_HEIGHT}
EOF`
else
aspect=`bc <<EOF
scale=0
100*$ID_VIDEO_ASPECT
EOF`
fi
if [ $aspect -gt 155 ]; then
dvdaspect="16/9"
else
dvdaspect="4/3"
fi
echo "Working directory: $workdir"
echo "Source:"
echo " ${ID_VIDEO_WIDTH}x${ID_VIDEO_HEIGHT}@${ID_VIDEO_FPS}fps, aspect ${aspect}/100, ${ID_AUDIO_RATE}Hz."
case ${ID_VIDEO_FPS} in
29.970)
norm=ntsc
dsth=480
fps="29.970"
speed="1.0"
;;
23.976)
norm=pal
dsth=576
fps="25"
speed="1.042709376"
;;
25.000)
norm=pal
dsth=576
fps="25"
speed="1.0"
;;
*)
echo "Invalid fps value: ${ID_VIDEO_FPS}"
exit 1
;;
esac
dstrate="48000"
bitrate="8000"
dstw=720
border=16 # top and bottom border
scalew=`expr $dstw - $border \* 2`
scaleh=`expr $dsth - $border \* 2`
echo "Destination:"
echo " $norm ${dstw}x${dsth} ${dvdaspect} border=${border}."
forcesrate=`bc <<EOF
(${fps}*10*${ID_AUDIO_RATE}/${ID_VIDEO_FPS}+5)/10
EOF`
echo "Scaling to ${scalew}x${scaleh}"
echo "Resampling from ${forcesrate}Hz to ${dstrate}Hz."
echo
sleep 2
aopts="acodec=mp2:abitrate=224"
vopts="vcodec=mpeg2video:aspect=${dvdaspect}:vqmin=2:mbqmin=2:lmin=0.5:vbitrate=4000:vrc_minrate=400:vrc_maxrate=8000:vrc_buf_size=1835:mbd=2:keyint=15:vmax_b_frames=2:vpsize=2000:scplx_mask=0.2:trell:precmp=2:cmp=2:subcmp=2:cbp:mv0:psnr:vrc_eq=tex"
mplayeropts="-cache 8192 -nosound -fps $fps -sws 2 -vf pp=hb/vb/dr,denoise3d,scale=${scalew}:${scaleh},expand=${dstw}:${dsth} -vo yuv4mpeg -noframedrop"
mencoderopts="-sws 2 -ovc lavc -oac lavc -of mpeg stream.yuv"
if [ ! -f "$tmpwav" ]; then
echo "Dumping and normalizing audio stream..."
mplayer -speed $speed -srate $dstrate -vo null -vc dummy \
-aofile "$tmpwav" -ao pcm "$source" 2>/dev/null | statfilt
normalize "$tmpwav"
fi
echo "Video encoding pass 1..."
mkfifo stream.yuv
(mplayer $mplayeropts "$source" </dev/null 2>/dev/null | statfilt) &
mencoder -audiofile "$tmpwav" -lavcopts $aopts:$vopts:vpass=1 \
-o "$tmpmpg" -passlogfile "$tmplog" $mencoderopts 2>/dev/null >/dev/null
rm -f stream.yuv
echo "Video encoding pass 2..."
mkfifo stream.yuv
(mplayer $mplayeropts "$source" </dev/null 2>/dev/null | statfilt) &
mencoder -audiofile "$tmpwav" -lavcopts $aopts:$vopts:vpass=2 \
-o "$tmpmpg" -passlogfile "$tmplog" $mencoderopts 2>/dev/null >/dev/null
rm -f stream.yuv
echo "Dumping video stream..."
mplayer -dumpvideo -dumpfile "$tmpm2v" "$tmpmpg" 2>/dev/null >/dev/null
echo "Dumping audio stream..."
mplayer -dumpaudio -dumpfile "$tmpmp2" "$tmpmpg" 2>/dev/null >/dev/null
echo "Multiplexing..."
mplex -f8 -V -o "$result" "$tmpmp2" "$tmpm2v" 2>/dev/null >/dev/null
popd
rm -rf "$workdir" "$tmpm2v" "$tmpmpg"
---------------------------
The statfilt program simply filters mplayers very noisy output to get
only the status line:
---------- statfilt.c ----------
/*
* 2003 (C) by Tobias Diedrich <ranma at gmx.at>
*
* Licensed under GNU GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
struct termios ots;
void exit_handler(int signum)
{
printf("\nCatched signal %d, exiting...\n", signum);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &ots);
exit(1);
}
int main(int argc, char **argv)
{
struct termios ts;
struct sigaction sa;
int c;
tcgetattr(STDIN_FILENO, &ts);
ots = ts;
ts.c_lflag &= ~(ICANON | ECHO | ECHONL);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &ts);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = exit_handler;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
do {
for (;(c = getchar()) != EOF && c != '\r';);
for (;(c = getchar()) != EOF && c != '\n';) {
putchar(c);
fflush(stdout);
}
} while (c != EOF);
tcsetattr(STDIN_FILENO, TCSAFLUSH, &ots);
return 0;
}
--------------------------------
--
/* Tobias */ int main(int a,char **b){char i,j,t,*r=*++b;srand(getpid());for(;
*r;){for(;*r&&!isalpha(*r);r++);for(i=1;isalpha(r[i+1]);i++){j=rand()%i;t=r[i];
r[i]=r[++j];r[j]=t;}r+=i+1;}puts(*b);} /* PGP: http://9ac7e0bc.2ya.com */
np: McVaffe: http://remix.overclocked.org 99 - Final Fantasy Kaoss OC ReMix []
More information about the MPlayer-users
mailing list