/[amv]/amv.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /amv.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Thu Jul 19 21:16:30 2007 UTC (11 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 3058 byte(s)
added reference links on the web
1 dpavlin 3 #!/usr/bin/perl -w
2    
3     # amv.pl
4     #
5     # 07/19/07 19:21:39 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
6 dpavlin 7 #
7     # Various useful links used to produce this:
8     # http://www.moviecodec.com/topics/15431p1.html
9     # http://en.wikipedia.org/wiki/RIFF_(File_format)
10 dpavlin 3
11     use strict;
12    
13     use Data::Dump qw/dump/;
14     use Carp qw/confess/;
15    
16     my $path = shift @ARGV || die "usage: $0 movie.amv\n";
17    
18     open(my $fh, '<', $path) || die "can't open $path: $!";
19    
20 dpavlin 4 # offset in file
21     my $o = 0;
22    
23     # shared data hash
24     my $d;
25    
26 dpavlin 3 sub hex_dump {
27     my $bytes = shift || return;
28    
29     my $ascii = $bytes;
30     $ascii =~ s/\W/./gs;
31     my $hex = unpack('h*', $bytes);
32     $hex =~ s/(..)/$1 /g;
33     # calculate number of characters for offset
34 dpavlin 4 #my $d = length( sprintf("%x",length($bytes)) );
35     my $d = 4;
36 dpavlin 6 my $prefix = '#.';
37 dpavlin 3 while ( $hex =~ s/^((?:\w\w\s){1,16})// ) {
38 dpavlin 6 printf "$prefix %0${d}x | %-48s| %s\n", $o, $1, substr( $ascii, 0, 16 );
39     $prefix = '##';
40 dpavlin 3 if ( length($ascii) >= 16 ) {
41     $ascii = substr( $ascii, 16 );
42 dpavlin 4 $o += 16;
43 dpavlin 3 } else {
44 dpavlin 4 $o += length($ascii);
45 dpavlin 3 last;
46     }
47     }
48     }
49    
50     sub x {
51     my ($len,$format) = @_;
52    
53     my $bytes;
54     read($fh, $bytes, $len);
55    
56     my $r_len = length($bytes);
57     confess "read $r_len bytes, expected $len" if $len != $r_len;
58    
59     hex_dump( $bytes );
60    
61 dpavlin 4 if ( $bytes eq 'AMV_END_' ) {
62 dpavlin 5 warn "> end of file marker AMV_END_\n";
63 dpavlin 4 $d->{eof}++;
64     return;
65     }
66    
67 dpavlin 3 if ( $format ) {
68     my @data = unpack($format, $bytes);
69 dpavlin 4 warn "## unpacked = ",dump(@data),"\n";
70 dpavlin 3 return @data;
71     } else {
72     return $bytes;
73     }
74     }
75    
76     sub next_part {
77     my ( $expected_part, $expected_len, $skip ) = @_;
78     my ( $part, $len ) = x(8,'A4V');
79 dpavlin 4 return unless $len;
80 dpavlin 3 confess "not $expected_part but $part" if $expected_part ne $part;
81     if ( $expected_len ) {
82     confess "expected $expected_len bytes for $part got $len" if $len != $expected_len;
83     }
84 dpavlin 5 printf ">> %s - %d 0x%x bytes\n", $part, $len, $len;
85 dpavlin 3 x($len) if $skip;
86     return $len;
87     }
88    
89     my ( $riff, $amv ) = x(12, 'Z8Z4');
90     die "not RIFF but $riff" if $riff ne 'RIFF';
91     die "not AMV but $amv" if $amv ne 'AMV ';
92    
93 dpavlin 4 while ( ! defined($d->{eof}) ) {
94 dpavlin 3 my ( $list, $name ) = x(12,'A4x4A4');
95     die "not LIST but $list" if $list ne 'LIST';
96     print "> $list .. $name\n";
97    
98     if ( $name eq 'hdrl' ) {
99    
100     my $len = next_part( 'amvh', hex(38) );
101    
102     my @names = ( qw/ms_per_frame width height fps ss mm hh/ );
103     my $h;
104     map {
105     my $v = $_;
106     my $n = shift @names || die "no more names?";
107     $h->{$n} = $v;
108     } x($len, 'Vx28VVVx8CCv');
109    
110     printf "## %s %d*%d %s fps (%d ms/frame) %02d:%02d:%02d\n",
111     $h->{path},
112     $h->{width}, $h->{height}, $h->{fps}, $h->{ms_per_frame},
113     $h->{hh}, $h->{mm}, $h->{ss};
114    
115     $d->{amvh} = $h;
116    
117     } elsif ( $name eq 'strl' ) {
118    
119     next_part( 'strh', 0, 1 );
120     next_part( 'strf', 0, 1 );
121    
122 dpavlin 4 } elsif ( $name eq 'movi' ) {
123    
124     while (1) {
125     my $frame = $d->{movi}++;
126    
127     my $len = next_part( '00dc', 0, 1 );
128     last unless $len;
129     printf ">> %s 00dc - frame %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len;
130    
131     my $len = next_part( '01wb', 0, 1 );
132     printf ">> %s 01wb - frame %d audio %d 0x%x bytes\n", $name, $frame, $len, $len;
133     };
134    
135 dpavlin 3 } else {
136     die "unknown $list $name";
137     }
138     }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26