[MPlayer-users] Re: problem encoding a compliant DVD from an XviD source movie
Tobias Diedrich
ranma at tdiedrich.de
Sun Apr 15 10:13:35 CEST 2007
Joey Parrish wrote:
> On 4/14/07, Prabu(A.G.Oliveira) <mahaprabr at yahoo.com.br> wrote:
> >Hi friends from Mplayer&Mencoder list!!!
> >
> >I'm a beginner and I've been trying hard (without sucess) to encode some
> >movies to see on TV.
> >
> >for example, one of my source movie is:
> >
> >Lost_S03_E01.avi - VIDEO: [XVID] 608x336 24bpp 23.976 fps 1019.6
> >kbps (124.5 kbyte/s
> >
> >And I would like to put it on a dvd (with subtitles) to watch on tv.
>
> I tried to author compliant DVDs with MEncoder a couple years ago and
> had no success. But I would find it great to be able to do so. I'll
> try again over the next couple days, beginning with your options and
> report back what, if anything, works for me. I'll also compare
> results to TMPG, which isn't free but always works.
FWIW, I've used the following script with acceptable results in the
past (Well, mainly for encoding anime episodes with a Pioneer DV 535
as the target hardware player).
Uses Debian dotlockfile unless you modify the script.
#!/bin/bash
PATH="$PATH:/usr/local/bin:/bin:/usr/bin"
# $Id: transcode_to_mpeg2,v 1.22 2006-04-26 19:30:05 ranma Exp $
#
# needed software:
#
# midentify (mplayer/CONTRIB), mencoder [, mplayer]
# dotlockfile
# mplex (mjpegtools)
#
# 'constants' :)
# quantisation matrices from TMPGEnc
tmpgenc_intra_matrix="\
8,16,19,22,26,27,29,34,\
16,16,22,24,27,29,34,37,\
19,22,26,27,29,34,34,38,\
22,22,26,27,29,34,37,40,\
22,26,27,29,32,35,40,48,\
26,27,29,32,35,40,48,58,\
26,27,29,34,38,46,56,69,\
27,29,35,38,46,56,69,83"
tmpgenc_inter_matrix="\
16,17,18,19,20,21,22,23,\
17,18,19,20,21,22,23,24,\
18,19,20,21,22,23,24,25,\
19,20,21,22,23,24,26,27,\
20,21,22,23,25,26,27,28,\
21,22,23,24,26,27,28,30,\
22,23,24,26,27,28,30,31,\
23,24,25,27,28,30,31,33"
# default quantisation matrix from libavcodec for reference
default_intra_matrix="\
8,16,19,22,26,27,29,34,\
16,16,22,24,27,29,34,37,\
19,22,26,27,29,34,34,38,\
22,22,26,27,29,34,37,40,\
22,26,27,29,32,35,40,48,\
26,27,29,32,35,40,48,58,\
26,27,29,34,38,46,56,69,\
27,29,35,38,46,56,69,83"
default_inter_matrix="\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16"
# default mpeg4 quantisation matrix from libavcodec
mpeg4_intra_matrix="\
8,17,18,19,21,23,25,27,\
17,18,19,21,23,25,27,28,\
20,21,22,23,24,26,28,30,\
21,22,23,24,26,28,30,32,\
22,23,24,26,28,30,32,35,\
23,24,26,28,30,32,35,38,\
25,26,28,30,32,35,38,41,\
27,28,30,32,35,38,41,45"
mpeg4_inter_matrix="\
16,17,18,19,20,21,22,23,\
17,18,19,20,21,22,23,24,\
18,19,20,21,22,23,24,25,\
19,20,21,22,23,24,26,27,\
20,21,22,23,25,26,27,28,\
21,22,23,24,26,27,28,30,\
22,23,24,26,27,28,30,31,\
23,24,25,27,28,30,31,33"
# CG quantization matrices from TMPGEnc
cg_intra_matrix="\
8,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32,\
32,32,32,32,32,32,32,32"
cg_inter_matrix="\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16,\
16,16,16,16,16,16,16,16"
# (still hardcoded) defaults
intra_matrix="$mpeg4_intra_matrix" # quantisation matrix for I-Frames
inter_matrix="$mpeg4_inter_matrix" # quantisation matrix for P- and B-Frames
npass=3 # 3-pass encoding (should give less vbv buffer underruns than 2-pass)
dstrate="48000" # 48kHz sampling rate
bitrate="2000" # 4MBit bitrate
dstw=720 # 720 pixel destination width
border=16 # Width of black border
# cmp is used for macroblock decision
# dia is used for motion estimation
##cmp=10 # NSSE (noise preserving sum of squared differences)
##dia=3 # normal size 3 diamond
#cmp=2 # SATD (sum of absolute Hadamard transformed differences)
#dia=-2 # shape adaptive (fast) diamond with size 2
cmp=2 # SATD (sum of absolute Hadamard transformed differences)
dia=-4 # shape adaptive (fast) diamond with size 4
mplex=1 # Use mplex for muxing instead of MEncoder built-in muxer
aopts="acodec=mp2:abitrate=224"
cmpopts="ildctcmp=$cmp:precmp=$cmp:cmp=$cmp:subcmp=$cmp:mbcmp=$cmp:nssew=100"
diaopts="predia=$dia:dia=$dia"
# supported environment variables
#
# FORCEFPS: override fps value reported by midentify, might be broken
# MENCODEROPTS: additional options to pass on to mencoder
# e.g. '-endpos 60' for testing
# support functions
# cleanup was once called multiple times and thus made a function
cleanup() {
trap '' ERR
echo "Done encoding `date`" >> "$logfile"
rm -f "$tmpwav" "$tmpm2v" "$tmpmp2"
rm -rf "$workdir"
dotlockfile -u "$lockfile"
# kill -SIGTERM $tailpid
exit 0
}
# signal handlers
error() {
echo "Terminating due to error condition $1 `date`" >> "$logfile"
echo "Terminating due to error condition $1"
rm -rf "$workdir"
rm -f "$tmpwav"
dotlockfile -u "$lockfile"
# kill -SIGTERM $tailpid
exit 1
}
# did we get a source file name?
if [ ! -r "$1" ]; then
echo "Usage: $0 <sourcefile> [<destinationfile>]"
exit 0
fi
# be nice
renice 5 $$
# work out temporary filenames, lots of no longer used stuff here...
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
base="${source%avi}"
lockfile="${base}lock"
tmpbase="$tmpdir/`basename "${source%avi}"`"
logfile="${tmpbase}logfile"
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="${base}mpg"
# did we get a destination file name?
if [ "$2" != "" ]; then
if [ "`dirname "$2" | awk '{ print substr($0, 1, 1) }'`" != "/" ]; then
result="$wd/$2"
else
result="$2"
fi
fi
# we don't want to overwrite by accident
if [ -f "$result" ]; then
echo "Destination $result already exists, giving up"
exit 1
fi
# try locking locking the source file
if ! dotlockfile -l -r 0 "$lockfile"; then
echo "Could not lock $source, giving up"
exit 1
fi
# setup signal handlers
trap 'error "Exit status != 0"' ERR
trap 'error "SIGTERM received"' SIGTERM
trap 'error "SIGINT received"' SIGINT
# create logfile
touch "$logfile"
#tail -f "$logfile" &
#tailpid=$!
# all systems go
echo "Starting encode on `hostname` pid $$ `date`" > "$logfile"
# create temporary and working directory
test -d "$tmpdir" || mkdir "$tmpdir"
test -d "$workdir" || mkdir "$workdir"
pushd "$workdir"
# check out source file properties
eval `midentify "$source"`
if [ "$FORCEFPS" != "" ]; then
ID_VIDEO_FPS="$FORCEFPS"
fi
# is the aspect ratio stored in the source file?
# calculate aspect as width/height if not (assume square pixels, normal for avi)
if [ "$ID_VIDEO_ASPECT" = "0.0000" ]; then
aspect=`bc <<EOF
scale=0
100*${ID_VIDEO_WIDTH}/${ID_VIDEO_HEIGHT}/1
EOF`
else
aspect=`bc <<EOF
scale=0
100*$ID_VIDEO_ASPECT/1
EOF`
fi
# get scaled video fps
rate=`bc <<EOF
scale=0
1000*$ID_VIDEO_FPS/1
EOF`
echo "Rate: $rate"
# handle 120fps files
decimate=$((($rate+12000) / 24000))
decimated=$(($rate / $decimate))
if [ $decimate -gt 1 -a \
$decimated -gt 23000 -a \
$decimated -lt 25000 ]; then
echo "Decimated: $decimated (factor $decimate)"
rate=$decimated
else
decimate=1
fi
# determine desired output norm based on fps
if [ $rate -gt 27000 ]; then
norm=ntsc
dsth=480
fps="30000/1001" # ntsc
telecine=""
elif [ $rate -lt 24100 -a \
"$mplex" != "1" ]; then
norm=ntsc
dsth=480
fps="24000/1001" # telecined progressive
telecine=":telecine"
else
norm=pal
dsth=576
fps="25" # pal
telecine=""
fi
# determine needed speedup value to get from source fps to destination fps
speed=`bc <<EOF
scale=10
1000*$fps/$rate
EOF`
# get output mpeg aspect ratio
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."
# determine the scaling width/height
scalew=`expr $dstw - $border \* 2`
scaleh=`expr $dsth - $border \* 2`
echo "Speedup: $speed"
echo "Destination:"
echo " $norm ${dstw}x${dsth} ${dvdaspect} border=${border}."
#forcesrate=`bc <<EOF
#(100*${ID_AUDIO_RATE}*${fps}/${ID_VIDEO_FPS}+50)/100
#EOF`
echo "Scaling to ${scalew}x${scaleh}"
#echo "Resampling from ${forcesrate}Hz to ${dstrate}Hz."
echo "Using ${npass}pass-encoding"
echo
# we are ready to go
sleep 2
# refer to mencoder manpage for most options ^^;
#
# vqmin: minimum quantiser (should be 1)
# lmin: should be equal to or less than vqmin ('Minimum Lagrange multiplier for ratecontrol')
# vrc_maxrate: maximum allowed bitrate (7500kbit should be safe)
# vrc_buf_size: vbv buffer (1835 => 229KB, dvd standard (stupid option is in kbit))
# keyint: keyframe every 15 frames (dvd standard)
# vmax_b_frames: 0 => no b frames, 1 could be safe but might throw off ratecontrol
# mbd: 2 => high quality (macro block decision mode)
# trell: 'trellis searched quantization' => high quality
# vpsize: 2000 seems to improve hardware player compatibility ('video packet size')
# sc_threshold: scene change threshold
# cgop: closed gop
# filters:
# pp=ac => deblock+dering
# softskip: allows filters which need to see all frames (inverse telecine, temporal denoising, etc.)
# to function properly
# harddup: necessary for mpeg-encoding, always last in chain
vopts="vcodec=mpeg2video:aspect=${dvdaspect}:vbitrate=${bitrate}:lmin=0.9:vqmin=1:vrc_maxrate=7500:vrc_buf_size=1835:keyint=15:vmax_b_frames=0:vpsize=2000:mbd=2:$cmpopts:$diaopts:trell" #trell:cbp:mv0
vopts="${vopts}:sc_threshold=-1500" # 23:45 <@nicodvb> poirierg: using sc_threshold=-1500 improved a lot the quality for my encodings
#vopts="${vopts}:cgop"
vopts="${vopts}:inter_matrix=${inter_matrix}:intra_matrix=${intra_matrix}"
mpegopts="format=dvd:vaspect=${dvdaspect}${telecine}"
prefilters="pp=ac"
postfilters="scale=${scalew}:${scaleh},expand=${dstw}:${dsth}"
filters="$prefilters,softskip,$postfilters,harddup"
mencoderopts="$MENCODEROPTS -slang en -alang ja -subfont-text-scale 3 -subpos 95 -subalign 2 -speed $speed -ofps $fps -oac lavc -sws 2 -ssf ls=0.9:cs=0.9 -vf ${filters} -af lavcresample=$dstrate"
echo Audio Command line: mencoder -cache 1024 \
-o "$tmpmp2" \
-lavcopts $aopts \
-ovc copy \
-of rawaudio \
$mencoderopts \
"$source"
if [ "$mplex" = "1" ]; then
echo "Audio encoding..."
mencoder -cache 1024 \
-o "$tmpmp2" \
-lavcopts $aopts \
-ovc copy \
-of rawaudio \
$mencoderopts \
"$source"
mencoderopts="$mencoderopts -ovc lavc -of rawvideo"
else
mencoderopts="$mencoderopts -ovc lavc -of mpeg"
fi
echo Video Command line: mencoder -cache 1024 \
-o "$result" \
-lavcopts $aopts:$vopts:psnr:vpass=1 \
-mpegopts $mpegopts \
-passlogfile "$tmplog" \
$mencoderopts \
"$source"
pass=1
passopt=1
while [ $pass -le $npass ]; do
echo "Video encoding pass $pass..."
echo "Video encoding pass $pass... `date`" >> "$logfile"
outfile="$result"
if [ "$mplex" = "1" ]; then
outfile="$tmpm2v"
rm -f "$tmpm2v"
mkfifo "$tmpm2v"
mplex --verbose 0 -f8 -V -o "$result" "$tmpm2v" "$tmpmp2" &
fi
mencoder -cache 1024 \
-o "$outfile" \
-lavcopts $aopts:$vopts:psnr:vpass=$passopt \
-mpegopts $mpegopts \
-passlogfile "$tmplog" \
$mencoderopts \
"$source"
cp "$tmplog" "${tmplog}.$pass"
passopt=3
pass=$(($pass + 1))
done
popd
cleanup
--
Tobias PGP: http://9ac7e0bc.uguu.de
このメールは十割再利用されたビットで作られています。
More information about the MPlayer-users
mailing list