📄 do_diff_mae_cmo.pl
字号:
} elsif ($file =~ /^(DB|OL)/) { Msg('WORK', "Diffing WM9 $file"); my $suffix = ( -e "$file.mae.gz" ) ? ".gz" : ""; if (system("zdiff $file.mae$suffix $file.cmo$suffix")) { Msg('ERROR', "WM9 mismatch in $file"); } } else { Msg('ERROR', "File $file not supported!"); } } if ($num_idct_files > 10) { Msg('WORK', "Checking IDCT accuracy"); check_idct(); } elsif ($num_idct_files > 0) { Msg('WORK', "Not enough IDCT files passed to do accuracy checks"); } log_close() if defined($cl_opt{"log"});}# -------------------------------------------------sub print_report($$$$$) {# ------------------------------------------------- # Note: $mb, $sb are passed in for debugging # Note ij_diff is a maeerence my ($mb, $sb, $sb_diff, $mb_diff, $ij_diff) = @_; if (defined($cl_opt{"report"})) { Msg('Report', "Maximum total difference in a subblock : $sb_diff"); Msg('Report', "Maximum total difference in a macroblock: $mb_diff"); Msg('Report', "Peak difference at each entry:"); for (my $row = 0; $row < 8; $row++) { my $d_line = ""; for (my $col = 0; $col < 8; $col++) { $d_line .= sprintf("%2d ", $$ij_diff[$row * 8 + $col]); } Msg('Report', $d_line); } }}# -------------------------------------------------sub subblock_end ($$$$$$) {# ------------------------------------------------- # Note: All of the diff inputs are maeerences # Note: $mb, $sb are passed in for debugging my ($mb, $sb, $max_sb_diff, $max_ij_diff, $sb_diff, $ij_diff) = @_; if (defined($cl_opt{"report"})) { # Track subblock diffs $$max_sb_diff = max($$max_sb_diff, $$sb_diff); $$sb_diff = 0; for (my $i = 0; $i <= $#$ij_diff; $i++) { $$max_ij_diff[$i] = max($$max_ij_diff[$i], $$ij_diff[$i]); $$ij_diff[$i] = 0; } } if ($idct) { # Track # of entries $pe_total += 1; $oe_total += 64; }}# -------------------------------------------------sub macroblock_end($$$$) {# ------------------------------------------------- # Note: All of the diff inputs are maeerences # Note: $mb, $sb are passed in for debugging my ($mb, $sb, $max_mb_diff, $mb_diff) = @_; if ($mc and defined($cl_opt{"check_mc"})) { my $diff = $peak_diff{$mb} - $peak_mae{$mb}; if ($diff > $peak_diff) { my $line; $line .= sprintf("MacroBlock %4s ", $mb); $line .= sprintf("MC peak[%3s] ", $peak_diff{$mb}); $line .= sprintf("RefBlock peak[%s] ", $peak_mae{$mb}); $line .= sprintf("Diff %3s > Allowed %2s", $diff, $peak_diff); Msg('ERROR', $line); } else { Debug("For macroblock $mb post MC peak [$peak_diff{$mb}] <= RefBlock peak [$peak_mae{$mb}] OKAY"); } } if (defined($cl_opt{"report"})) { # Track macroblock level diffs $$max_mb_diff = max($$max_mb_diff, $$mb_diff); $$mb_diff = 0; }} # -------------------------------------------------sub do_diff($$$$) {# ------------------------------------------------- my ($file, $MAX) = @_; my $MIN = -1 * $MAX; Msg('WORK', "Diffing $file"); if (!file_open(\$file)) { Msg('ERROR', "Can't open $file, skipping"); return; } # Due to way MP4 maeerence code processes Intra frames IDCT on those # frames is a special case. The output is already unsigned my $signed = (($iquant or $idct) and !($mp4 and $idct and ($file =~/Intra/))) ? 1 : 0; my $sb_row = 0; # Row in subblock my ($sb_num, $mb_num) = (0, 0); # Subblock, macroblock number my ($sb_diff, $max_sb_diff) = (0, 0); # Maximum total difference in a subblock my ($mb_diff, $max_mb_diff) = (0, 0); # Maximum total difference in a macroblock my @ij_diff = ( # Peak difference in each location 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); my @max_ij_diff = @ij_diff; my ($in, $out, $len) = (0, 0, 0); my ($done, $first_macroblock, $first_subblock) = (0, 1, 0); while (!$done) { my ($m_line, $r_line); my $eof = file_getlines(\$m_line, \$r_line, 0); if ($eof) { macroblock_end($mb_num, $sb_num, \$max_mb_diff, \$mb_diff); subblock_end($mb_num, $sb_num, \$max_sb_diff, \@max_ij_diff, \$sb_diff, \@ij_diff); Debug("EOF detected!"); print_report($mb_num, $sb_num, $max_sb_diff, $max_mb_diff, \@max_ij_diff); last; } if ($m_line =~ /MacroBlock #(\d+)/) { my $mb_num_next = $1; my $check_mb; if ($r_line =~ /MacroBlock #(\d+)/) { $check_mb = $1; } else { Msg('ERROR', "Out of sync, found MacroBlock in CMO but not in MAE!"); } if ($check_mb != $mb_num_next) { Msg('ERROR', "Out of sync, found MacroBlock $mb_num_next for CMO but $check_mb for MAE!"); } if ($first_macroblock) { $first_macroblock = 0; } else { macroblock_end($mb_num, $sb_num, \$max_mb_diff, \$mb_diff); } if ($m_line =~ /bi-directional/i) { my $found = 0; for (my $try = 0; $try < 2; $try++) { file_getlines(\$m_line, \$r_line, 0) and Msg('ERROR', "File shouldn't end after MacroBlock line!"); if ($m_line =~ /forward/i) { $mb_num_next .= "f"; $found = 1; last; } elsif ($m_line =~ /backward/i) { $mb_num_next .= "b"; $found = 1; last; } } if (!$found) { Msg('ERROR', "Don't understand line(s) after Bi-Directional Macroblock!"); } } $mb_num = $mb_num_next; Debug("Processing macroblock $mb_num") if defined($cl_opt{"debug"}); $peak_diff{$mb_num} = 0; $first_subblock = 1; } elsif ($m_line =~ /(\w+) Block/) { my $sb_num_next = $1; if ($first_subblock) { $first_subblock = 0; } else { subblock_end($mb_num, $sb_num, \$max_sb_diff, \@max_ij_diff, \$sb_diff, \@ij_diff); } $sb_num = $sb_num_next; Debug("Processing subblock $sb_num") if defined($cl_opt{"debug"}); $sb_row = 0; } elsif ($m_line =~ /^\$/) { # Ignore unused lines } else { my @m_pixel = split(/\s*:\s*/, $m_line); my @r_pixel = split(/\s*:\s*/, $r_line); my $d_line = ""; my $size = $#m_pixel + 1; for (my $i = 0; $i < $size; $i++) { my $entry = $sb_row * $size + $i; # Get pixel my ($m_pixel, $r_pixel); if ($signed) { # IQUANT, IDCT are SIGNED if ($len == 0) { $len = length($m_pixel[$i]); if ($len == 2) { $in = "C"; $out = "c"; } elsif ($len == 4) { $in = "S"; $out = "S"; } elsif ($len == 8) { $in = "I"; $out = "i"; } else { Msg('ERROR', "Invalid entry in IQUANT or IDCT, expected 8, 16, or 32-bit"); } } $m_pixel = unpack($out, pack($in, hex($m_pixel[$i]))); $r_pixel = unpack($out, pack($in, hex($r_pixel[$i]))); } else { # MC, RefBlocks, and Final output are UNSIGNED $m_pixel = hex($m_pixel[$i]); $r_pixel = hex($r_pixel[$i]); } my $diff = $m_pixel - $r_pixel; # Track diffs for IDCT if ($idct) { $ome_num += $diff; $omse_num += abs($diff); $pme_num[$entry] += $diff; $pmse_num[$entry] += abs($diff); } if (defined($cl_opt{"report"})) { # Track other interesting things $sb_diff += abs($diff); $mb_diff += abs($diff); $ij_diff[$entry] = max($ij_diff[$entry], abs($diff)); } if ($cl_opt{"check_mc"}) { $peak_diff{$mb_num} = max($peak_diff{$mb_num}, abs($diff)); }# # Basic checks# my $pixel_max = ($iquant or ($idct and $wm9)) ? 65535 : 255;# if (($m_pixel > $pixel_max) or ($r_pixel > $pixel_max) or# ($m_pixel < (-1 * $pixel_max)) or ($r_pixel < (-1 * $pixel_max))) { # Msg('INFO', sprintf("Ref pixel: 0x%-8x", $r_pixel));# Msg('INFO', sprintf("CMO pixel: 0x%-8x", $m_pixel));# Msg('ERROR', "MB$mb_num SB$sb_num Detected > $pixel_max pixel!");# } if (($diff > $MAX) or ($diff < $MIN)) { my $line; $line = sprintf("$file: MacroBlock %4s Block %3s ", $mb_num, $sb_num); $line .= sprintf("Diff: %3d > Allowed: %3d ", $diff, $MAX); $line .= sprintf("MAE: 0x%-8x CMO: 0x%-8x", $r_pixel, $m_pixel); Msg('ERROR', $line); } $d_line .= sprintf("%2d ", $diff) if defined($cl_opt{"debug"}); } Debug($d_line) if defined($cl_opt{"debug"}); $sb_row++; } } # Save for motion compensation check if ($cl_opt{"check_mc"}) { %peak_mae = %peak_diff; } if ($zipped) { $M->gzclose(); $R->gzclose(); } else { $M->close(); $R->close(); }}# -------------------------------------------------sub graceful_shutdown {# ------------------------------------------------- log_close();}# -------------------------------------------------sub max($$) {# ------------------------------------------------- my ($a, $b) = @_; return ($a > $b) ? $a : $b;} #--------------------------------------------------------------------------## Log functions#my ($log_fh, $log_open);$log_fh = new FileHandle;$log_open = 0; # -------------------------------------------------sub log_open($) {# ------------------------------------------------- my ($log) = @_; $log_fh->open(">$log") or Msg('ERROR', "can't open $log"); my $date = localtime; print $log_fh "# [$date] created\n"; $log_open = 1;}# -------------------------------------------------sub log_close() {# ------------------------------------------------- return unless $log_open; my $date = localtime; print $log_fh "# [$date] closed\n"; $log_fh->close(); $log_open = 0;}# -------------------------------------------------sub Msg($$) {# ------------------------------------------------- my ($sev, $msg) = @_; print "$sev: $msg\n"; if ($log_open) { print $log_fh "# $sev: $msg\n"; } if ($sev eq "ERROR") { $error = 1; } if (!defined($cl_opt{"keep_going"}) and $sev eq "ERROR") { ::graceful_shutdown(); exit(1); }}# -------------------------------------------------sub Debug($) {# ------------------------------------------------- my ($msg) = @_; if (defined($cl_opt{"debug"})) { Msg('DEBUG', $msg); }}##--------------------------------------------------------------------------main();if ($error) { printf "FAIL: Too many errors\n"; exit(1);} else { printf "PASS: Differences within tolerances\n"; exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -