[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