BillHungNet


powered by FreeFind 

Video Encoding Resolution vs Bitrate by Experience

[2009-12-30 London Bill Hung]

This page describes the video encoding formats I used. The data came from my own experience of reducing the bitrate of the video and then looking at the effect on the final video.
I usually lower the bitrate to a point where I see some undesirable effects, and then I will adjust the bitrate upward until the video looks good. The process is quite iterative and
time-consuming, and so far I haven't found a better tool than my naked eye to identify those chunky blocks.

  1. Table of Content
  2. Video Encoding Resolution vs Bitrate by Experience
    1. The Resolution vs Bitrate Table
    2. The Command Used
      1. H.264, ffmpeg
      2. Xvid. perl scipt + ffmpeg
      3. FLV, perl script + ffmpeg + yamdi (for injecting meta data)

The Resolution vs Bitrate Table

This is the table about the relationship of video format, the resolution, and the final video size. These are parameters I actually used for my videos.

H.264
320x240 400kbps=3.6MB/min, half 480p
624x352, 400kbps-500kbps, 500kbps = 4MB/min, half 1280x702, 300kbps=2.4MB/min, 386kbps=3MB/min
Xvid
320x240 385kbps=3.6MB/min, 200kbps=1.6MB/min150kbps=1.2MB/min
640x360 1Mbps
480p 500kbps, 768kbps=6.2MB/min, 1Mbps
FLV
320x180, 500kbps-550kbps, 500kbps=2.4MB/min(qmin=4) ~ 4.2MB/min(qmin=2)
480x270, 550kbps=3.7MB/min(qmin=4)
640x360, 550kbps=4.2MB/min(qmin=4)

The Command Used

The commands I use are contantly evolving. And here are the ones I currently use now. The commands below have evolved over the 100+ videos I converted.
The highlighted values in <brackets> should be replaced with actual values.

H.264, ffmpeg

ffmpeg -i <filename> -pass 1 -threads 2 -vcodec libx264 -b <bitrate> -aspect <aspect, 4:3 or 16:9> -s <width x height> -g 240 -bf 3 -refs 6 -b_strategy 1 -keyint_min 25 -qmin 10 -qmax 51 -subq 7 \
-partitions +parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 \
-flags2 +mixed_refs+dct8x8+bpyramid+wpred \
-me_method umh -me_range 16 -coder 1 -trellis 1 \
-an <filename>
ffmpeg -i <filename> -pass 2 -threads 2 -vcodec libx264 -b <bitrate> -aspect <aspect, 4:3 or 16:9> -s <width x height> -g 240 -bf 3 -refs 6 -b_strategy 1 -keyint_min 25 -qmin 10 -qmax 51 -subq 7 \
-partitions +parti8x8+parti4x4+partp8x8+partp4x4+partb8x8 \
-flags2 +mixed_refs+dct8x8+bpyramid+wpred \
-me_method umh -me_range 16 -coder 1 -trellis 1 \
-acodec libfaac -ab 64k <filename>

Xvid. perl scipt + ffmpeg

#!perl -w
use POSIX; #needed for ceil

#1. init variables
$folder = '<input folder path>';
$outdir = '<output folder path>';
$outdir = $outdir . '/';
$folder = $folder . '/';
$folder =~ s/\\/\//g; #where the files are
print "folder:".$folder."\n";
chdir $folder; #change directory

#2. print all filenames
# @files = <*.avi>;
# foreach $file (@files){
# print $file, "\n";
# }


#video parameters
#3. process all files
@files = <*.avi>;
foreach $file (@files){
$aspect = "<resolution, width x height>";
$aspectString = "-aspect 16:9 -s ${aspect}";
$audioRate = 64;
$sampleRate = 48000;
$bitrate = <bitrate>;
$fps = <frame per second>;
$keyframe = ceil($fps) * 6;
#conversion parameters
$is1pass = 0; #do 1-pass (1) or 2-pass (0)
$hasSound = 1; #to have sound (1), or no sound (0)
#file name parameters
$tempfile = $outdir."$file.temp.avi";
$file =~ m/^(.*?)\.?([^\.]*)$/; #match the extension for subfixes
$extension = '.'.$2;
$subfix = ".xvid.".$aspect.".".$bitrate."bps.".$fps."fps.".($sampleRate/1000)."kbps.avi";
$output = $file;
$output =~ s/$extension/$subfix/;
$output = $outdir.$file;
$infile = $folder.$file;
#don't modify below this line
if ($is1pass) { #1-pass
$command = "ffmpeg -y -i \"$infile\" -b ${bitrate}k -r ${fps} -g ${keyframe} -vcodec libxvid ${aspectString}";
if ($hasSound){ #has sound
$command .= " -acodec libmp3lame -ac 1 -ar ${sampleRate} -ab ${audioRate}k \"$output\" ";
}else{ #no sound
my $endStr = ($sampleRate/1000)."kbps.avi";
$output =~ s/${endStr}/0kbps.avi/;
$command .= " \"$output\" ";
}
print "$command\n"; `$command`;
}
else { #2-pass
# to get the time string, for example 20090329_174735
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
undef $wday; undef $isdst; undef $yday;
$log = sprintf "log%4d%02d%02d_%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
$command = "ffmpeg -y -i \"$infile\" -r ${fps} -g ${keyframe} -vcodec libxvid ${aspectString} -b ${bitrate}k -an -pass 1 -threads 2 -bf 2 -passlogfile ${log} \"$tempfile\"";
print "$command\n"; `$command`;
$command = "ffmpeg -y -i \"$infile\" -r ${fps} -g ${keyframe} -vcodec libxvid ${aspectString} -b ${bitrate}k -acodec libmp3lame -ac 1 -ar ${sampleRate} -ab ${audioRate}k -pass 2 -threads 2 -bf 2 -passlogfile ${log} \"$output\"";
print "$command\n"; `$command`;
}
}

FLV, perl script + ffmpeg + yamdi (for injecting meta data)

#!perl -w
use POSIX; #needed for ceil

#1.1 init variables, need changes
$folder = '<input folder path>';
$outdir = '<output folder path>';
#1.2 init variables, do not change
$outdir = $outdir . '/';
$folder = $folder . '/';
$folder =~ s/\\/\//g; #where the files are
#print "folder:".$folder."\n";
chdir $folder; #change directory

#2. print all filenames
# @files = <*.avi>;
# foreach $file (@files){
# print $file, "\n";
# }


#video parameters
#3. process all files
@files = <*.avi>;
foreach $file (@files){
$aspect = "<width x height>";
$aspectString = "-aspect <aspect ratio, 16:9 or 4:3> -s ${aspect}";
$audioRate = 32;
$sampleRate = 22050;
$bitrate = <bitrate>;
$fps = <frame per second>;
$keyframe = ceil($fps) * 6;
#conversion parameters
$is1pass = 0; #do 1-pass (1) or 2-pass (0)
$hasSound = 1; #to have sound (1), or no sound (0)
#file name parameters
$tempfile = $outdir."$file.temp.avi";
$file =~ m/^(.*?)\.?([^\.]*)$/; #match the extension for subfixes
$extension = '.'.$2;
$subfix = ".xvid.".$aspect.".".$bitrate."bps.".$fps."fps.".($sampleRate/1000)."kbps.avi";
$output = $file;
$output =~ s/$extension/$subfix/;
$output = $outdir.$output;
$infile = $folder.$file;
#don't modify below this line
if ($is1pass) { #1-pass
$command = "ffmpeg -y -i \"$infile\" -b ${bitrate}k -r ${fps} -g ${keyframe} -vcodec flv ${aspectString}";
if ($hasSound){ #has sound
$command .= " -acodec libmp3lame -ac 1 -ar ${sampleRate} -ab ${audioRate}k \"$output\" ";
}else{ #no sound
my $endStr = ($sampleRate/1000)."kbps.avi";
$output =~ s/${endStr}/0kbps.avi/;
$command .= " \"$output\" ";
}
print "$command\n"; `$command`;
}
else { #2-pass
# to get the time string, for example 20090329_174735
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
undef $wday; undef $isdst; undef $yday;
$log = sprintf "log%4d%02d%02d_%02d%02d%02d",$year+1900,$mon+1,$mday,$hour,$min,$sec;
$command = "ffmpeg -y -i \"$infile\" -r ${fps} -g ${keyframe} -vcodec libxvid ${aspectString} -b ${bitrate}k -an -pass 1 -threads 2 -qmin 4 -qmax 51 -passlogfile ${log} \"$tempfile\"";
print "$command\n"; `$command`;
$command = "ffmpeg -y -i \"$infile\" -r ${fps} -g ${keyframe} -vcodec libxvid ${aspectString} -b ${bitrate}k -acodec libmp3lame -ac 1 -ar ${sampleRate} -ab ${audioRate}k -pass 2 -threads 2 -qmin 4 -qmax 51 -passlogfile ${log} \"$output\"";
print "$command\n"; `$command`;

#FLV pass
$outflv = $output;
$outflv =~ s/.avi/.flv/;
$command = "ffmpeg -y -i \"$output\" -r ${fps} -g ${keyframe} -vcodec flv ${aspectString} -b ${bitrate}k -an -pass 1 -qmin 4 -qmax 51 -passlogfile ${log} \"$tempfile.flv\"";
print "$command\n"; `$command`;
$command = "ffmpeg -y -i \"$output\" -r ${fps} -g ${keyframe} -vcodec flv ${aspectString} -b ${bitrate}k -acodec libmp3lame -ac 1 -ar 22050 -ab 32k -pass 2 -qmin 4 -qmax 51 -passlogfile ${log} \"$outflv\"";
print "$command\n"; `$command`;

#YAMDI pass, meta data
$metaflv = $outflv;
$metaflv =~ s/.flv/.meta.flv/;
$command = "yamdi -i \"$outflv\" -o \"$metaflv\"";
print "$command\n"; `$command`;
}
}