/[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

Diff of /amv.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 13 by dpavlin, Fri Jul 20 16:55:33 2007 UTC revision 27 by dpavlin, Sat Aug 18 11:21:40 2007 UTC
# Line 9  Line 9 
9  # http://en.wikipedia.org/wiki/RIFF_(File_format)  # http://en.wikipedia.org/wiki/RIFF_(File_format)
10  # http://www.obrador.com/essentialjpeg/HeaderInfo.htm  # http://www.obrador.com/essentialjpeg/HeaderInfo.htm
11  # http://lists.helixcommunity.org/pipermail/datatype-dev/2005-January/001886.html  # http://lists.helixcommunity.org/pipermail/datatype-dev/2005-January/001886.html
12    # http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
13    # http://wiki.multimedia.cx/index.php?title=IMA_ADPCM
14    
15  use strict;  use strict;
16    
17  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
18  use Carp qw/confess/;  use Carp qw/confess/;
19  use File::Path;  use File::Path;
20    use Getopt::Long;
21    
22  my $dump = 0;  my $dump_amv = 0;
23    my $dump_video = 0;
24    my $dump_jpeg = 0;
25    my $dump_audio = 0;
26  my $debug = 0;  my $debug = 0;
27    my $verbose = 0;
28    my $dump_dir = '/tmp/dump/';
29    my $dump_avi = "dump.avi";
30    my $no_jpeg_header = 0;
31    my $jpeg_q = 100;
32    my $jpegtran;
33    
34    GetOptions(
35            "dump-amv!"             => \$dump_amv,
36            "dump-video!"   => \$dump_video,
37            "dump-jpeg!"    => \$dump_jpeg,
38            "dump-audio!"   => \$dump_audio,
39            "debug!"                => \$debug,
40            "dump-dir=s"    => \$dump_dir,
41            "no-jpeg-headers!" => \$no_jpeg_header,
42            "jpegtran=s"    => \$jpegtran,
43            "verbose!"              => \$verbose,
44    );
45    
46  my $path = shift @ARGV || die "usage: $0 movie.amv\n";  my $path = shift @ARGV || die "usage: $0 movie.amv\n";
47    
48  my $dump_dir = '/tmp/dump/';  # by default, flip frames
49    #$jpegtran = '-flip vertical' unless defined($jpegtran);
50    
51  rmtree $dump_dir if -e $dump_dir;  rmtree $dump_dir if -e $dump_dir;
52  mkpath $dump_dir || die "can't create $dump_dir: $!";  mkpath $dump_dir || die "can't create $dump_dir: $!";
53    
# Line 34  my $o = 0; Line 60  my $o = 0;
60  my $d;  my $d;
61    
62  sub hex_dump {  sub hex_dump {
         return unless $dump;  
   
63          my ( $bytes, $offset ) = @_;          my ( $bytes, $offset ) = @_;
64          return unless $bytes;          return unless $bytes;
65    
# Line 77  sub x { Line 101  sub x {
101          my $r_len = length($bytes);          my $r_len = length($bytes);
102          confess "read $r_len bytes, expected $len" if $len != $r_len;          confess "read $r_len bytes, expected $len" if $len != $r_len;
103    
104          hex_dump( $bytes );          if ( $dump_amv ) {
105                    print "## raw $len bytes\n";
106                    hex_dump( $bytes );
107            }
108    
109          if ( $bytes eq 'AMV_END_' ) {          if ( $bytes eq 'AMV_END_' ) {
110                  warn "> end of file marker AMV_END_\n";                  print "> end of file marker AMV_END_\n" if $dump_video;
111                  $d->{eof}++;                  $d->{eof}++;
112                  return;                  return;
113          }          }
114    
115          if ( $format ) {          if ( $format ) {
116                  my @data = unpack($format, $bytes);                  my @data = unpack($format, $bytes);
117                  warn "## unpacked = ",dump(@data),"\n" if $debug;                  print "## unpacked = ",dump(@data),"\n" if $debug;
118                  return @data;                  return @data;
119          } else {          } else {
120                  return $bytes;                  return $bytes;
# Line 102  sub next_part { Line 129  sub next_part {
129          if ( $expected_len ) {          if ( $expected_len ) {
130                  confess "expected $expected_len bytes for $part got $len" if $len != $expected_len;                  confess "expected $expected_len bytes for $part got $len" if $len != $expected_len;
131          }          }
132          printf "<< %s - %d 0x%x bytes\n", $part, $len, $len;          printf "## next_part %s - %d 0x%x bytes\n", $part, $len, $len if $debug;
133          x($len) if $skip;          x($len) if $skip;
134          return $len;          return $len;
135  }  }
136    
137  sub huffman {  sub quality {
138            my @table = @_;
139            die "quantization matrice needs to have 64 bytes!" if $#table != 63;
140    
141            my $in = join('', map { chr($_) } @table );
142            my $out;
143    
144            foreach my $t ( @table ) {
145                    $t = int( ( $t * $jpeg_q ) / 100 );
146                    $t = 255 if $t > 255;
147                    $out .= chr($t);
148            }
149    
150            if ( $dump_video ) {
151                    print "## quantization table original\n";
152                    hex_dump( $in );
153                    print "## quantization table for $jpeg_q %\n";
154                    hex_dump( $out );
155            }
156    
157            return $out;
158    }
159    
160    sub mp3_frame {
161            my $frame = join('',
162                    # Frame sync (all bits set)
163                    1 x 11 .
164                    # MPEG Audio version ID
165                    # 00 - MPEG Version 2.5 (unofficial)
166                    # 01 - reserved
167                    # 10 - MPEG Version 2 (ISO/IEC 13818-3)
168                    # 11 - MPEG Version 1 (ISO/IEC 11172-3)
169                    1,0,
170                    # Layer description
171                    # 00 - reserved
172                    # 01 - Layer III
173                    # 10 - Layer II
174                    # 11 - Layer I
175                    0,1,
176                    # Protection bit
177                    # 0 - Protected by CRC (16bit crc follows header)
178                    # 1 - Not protected
179                    0,
180                    # Bitrate index
181                    0,0,0,0,
182                    # Sampling rate frequency index (22050)
183                    0,0,
184                    # Padding bit
185                    # 0 - frame is not padded
186                    # 1 - frame is padded with one extra slot
187                    0,
188                    # Private bit
189                    0,
190                    # Channel Mode
191                    # 00 - Stereo
192                    # 01 - Joint stereo (Stereo)
193                    # 10 - Dual channel (2 mono channels)
194                    # 11 - Single channel (Mono)
195                    1,1,
196                    # Mode extension (Only if Joint stereo)
197                    0,0,
198                    # Copyright
199                    0,
200                    # Original
201                    0,
202                    # Emphasis
203                    # 00 - none
204                    # 01 - 50/15 ms
205                    # 10 - reserved
206                    # 11 - CCIT J.17
207                    0,0,
208            );
209    
210            die "frame must have 32 bits, not ", length($frame), " for $frame" if length($frame) != 32;
211    
212            my $bits = pack("b32", $frame);
213    
214            die "packed bits must be 4 bytes, not $bits" if length($bits) != 4;
215    
216  # JPEG DHT Segment for YCrCb omitted from MJPG data          my $t = $frame;
217  return          $t =~ s/(.{8})/$1 /g;
218  "\xFF\xC4\x01\xA2" .          warn "## mp3 frame frame = $t\n";
 "\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00" .  
 "\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x01" .  
 "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00" .  
 "\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x10\x00" .  
 "\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7D" .  
 "\x01\x02\x03\x00\x04\x11\x05\x12\x21\x31\x41\x06\x13\x51\x61" .  
 "\x07\x22\x71\x14\x32\x81\x91\xA1\x08\x23\x42\xB1\xC1\x15\x52" .  
 "\xD1\xF0\x24\x33\x62\x72\x82\x09\x0A\x16\x17\x18\x19\x1A\x25" .  
 "\x26\x27\x28\x29\x2A\x34\x35\x36\x37\x38\x39\x3A\x43\x44\x45" .  
 "\x46\x47\x48\x49\x4A\x53\x54\x55\x56\x57\x58\x59\x5A\x63\x64" .  
 "\x65\x66\x67\x68\x69\x6A\x73\x74\x75\x76\x77\x78\x79\x7A\x83" .  
 "\x84\x85\x86\x87\x88\x89\x8A\x92\x93\x94\x95\x96\x97\x98\x99" .  
 "\x9A\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xB2\xB3\xB4\xB5\xB6" .  
 "\xB7\xB8\xB9\xBA\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3" .  
 "\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8" .  
 "\xE9\xEA\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\x11\x00\x02" .  
 "\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02\x77\x00" .  
 "\x01\x02\x03\x11\x04\x05\x21\x31\x06\x12\x41\x51\x07\x61\x71" .  
 "\x13\x22\x32\x81\x08\x14\x42\x91\xA1\xB1\xC1\x09\x23\x33\x52" .  
 "\xF0\x15\x62\x72\xD1\x0A\x16\x24\x34\xE1\x25\xF1\x17\x18\x19" .  
 "\x1A\x26\x27\x28\x29\x2A\x35\x36\x37\x38\x39\x3A\x43\x44\x45" .  
 "\x46\x47\x48\x49\x4A\x53\x54\x55\x56\x57\x58\x59\x5A\x63\x64" .  
 "\x65\x66\x67\x68\x69\x6A\x73\x74\x75\x76\x77\x78\x79\x7A\x82" .  
 "\x83\x84\x85\x86\x87\x88\x89\x8A\x92\x93\x94\x95\x96\x97\x98" .  
 "\x99\x9A\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xB2\xB3\xB4\xB5" .  
 "\xB6\xB7\xB8\xB9\xBA\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2" .  
 "\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8" .  
 "\xE9\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA";  
219    
220            return $bits;
221  }  }
222    
223    my @subframes;
224    my $frame_nr = 1;
225    
226    # how many subframes to join into single frame?
227    my $join_subframes = 0;
228    
229  sub mkjpg {  sub mkjpg {
230          my ($path,$data) = @_;          my ($data) = @_;
         open(my $fh, '>', $path) || die "can't create $path: $!";  
231    
232          confess "no SOI marker in data" if substr($data,0,2) ne "\xFF\xD8";          confess "no SOI marker in data" if substr($data,0,2) ne "\xFF\xD8";
233          $data = substr($data,2);          confess "no EOI marker in data" if substr($data,-2,2) ne "\xFF\xD9";
234            $data = substr($data,2,-2);
235    
236            if ( $#subframes < ( $join_subframes - 1 ) ) {
237                    push @subframes, $data;
238                    print "## saved $frame_nr/", $#subframes + 1, " subframe of ", length($data), " bytes\n" if $debug;
239                    return;
240            }
241    
242            my $w = $d->{amvh}->{width} || die "no width?";
243            my $h = $d->{amvh}->{height} || confess "no height?";
244    
245          my $header =          my $header =
246                  "\xFF\xD8".     # Start of Image (SOI) marker          # Start of Image (SOI) marker
247  #------------------------------------------------------------------          "\xFF\xD8".
248                  "\xFF\xE0".     # JFIF marker          # JFIF marker
249            "\xFF\xE0".
250          pack("nZ5CCCnnCC",          pack("nZ5CCCnnCC",
251                  16,                     # length                  16,                     # length
252                  'JFIF',         # identifier                  'JFIF',         # identifier (JFIF)
253                  1,1,            # version                  1,1,            # version
254                  0,                      # units (none)                  0,                      # units (none)
255                  1,1,            # X,Y density                  1,1,            # X,Y density
256                  0,0,            # X,Y thumbnail                  0,0,            # X,Y thumbnail
257          ).          ).
258  #------------------------------------------------------------------          "\xFF\xFE".
259          "\xFF\xC0".     # Start of frame          "\x00\x3CCREATOR: amv dumper (compat. IJG JPEG v62), quality = 100\n".
260            # quantization table (quaility=100%)
261            "\xFF\xDB".
262            "\x00\x43".
263            # 8 bit values, table 1
264            "\x00".
265            quality(
266        0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E,
267        0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
268        0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
269        0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33,
270        0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44,
271        0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57,
272        0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71,
273        0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63,
274            ).
275            "\xFF\xDB".
276            "\x00\x43".
277            # 8 bit values, table 1
278            "\x01".
279            quality(
280        0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2F, 0x1A,
281        0x1A, 0x2F, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
282        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
283        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
284        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
285        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
286        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
287        0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
288            ).
289            # start of frame
290            "\xFF\xC0".
291          pack("ncnncc9",          pack("ncnncc9",
292                  17,                     # len                  17,                     # len
293                  8,                      # sample precision in bits                  8,                      # sample precision in bits
294                  120,160,        # X,Y size                  $h,$w,          # X,Y size
295                  3,                      # number of components                  3,                      # number of components
296                  1,0x21,0,       # Component ID, H+V sampling factors, Quantization table number                  1,0x22,0,       # Component ID, H+V sampling factors, Quantization table number
297                  2,0x11,1,                  2,0x11,1,
298                  3,0x11,1,                  3,0x11,1,
299          ).          ).
 #------------------------------------------------------------------  
         "\xFF\xDB".             # Define Quantization table marker  
         "\x00\x84".             # len  
         "\x00".                 # 8 bit values, (byte) table 0  
         "\x10\x0B\x0C\x0E\x0C".  
         "\x0A\x10\x0E\x0D\x0E".  
         "\x12\x11\x10\x13\x18".  
         "\x28\x1A\x18\x16\x16".  
         "\x18\x31\x23\x25\x1D".  
         "\x28\x3A\x33\x3D\x3C".  
         "\x39\x33\x38\x37\x40".  
         "\x48\x5C\x4E\x40\x44".  
         "\x57\x45\x37\x38\x50".  
         "\x6D\x51\x57\x5F\x62".  
         "\x67\x68\x67\x3E\x4D".  
         "\x71\x79\x70\x64\x78".  
         "\x5C\x65\x67\x63".  
         "\x01".         # 8 bit values, (byte) table 1  
         "\x11\x12\x12\x18\x15".  
         "\x18\x2F\x1A\x1A\x2F".  
         "\x63\x42\x38\x42\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63\x63".  
         "\x63\x63\x63\x63".  
 #------------------------------------------------------------------  
 #       huffman("\x00").        # 0 DC  
 #       huffman("\x01").        # 1 DC  
 #       huffman("\x10").        # 0 AC  
 #       huffman("\x11").        # 1 AC  
 #------------------------------------------------------------------  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\x1F".             # Length (31 bytes)  
         "\x00".                 # DC, (byte) table 0  
         "\x00\x01\x05\x01\x01".  
         "\x01\x01\x01\x01\x00".  
         "\x00\x00\x00\x00\x00".  
         "\x00\x00\x01\x02\x03".  
         "\x04\x05\x06\x07\x08".  
         "\x09\x0A\x0B".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\xB5".             # Length (181 bytes)  
         "\x10".                 # AC, (byte) table 0  
         "\x00\x02\x01\x03\x03".  
         "\x02\x04\x03\x05\x05".  
         "\x04\x04\x00\x00\x01".  
         "\x7D\x01\x02\x03\x00".  
         "\x04\x11\x05\x12\x21".  
         "\x31\x41\x06\x13\x51".  
         "\x61\x07\x22\x71\x14".  
         "\x32\x81\x91\xA1\x08".  
         "\x23\x42\xB1\xC1\x15".  
         "\x52\xD1\xF0\x24\x33".  
         "\x62\x72\x82\x09\x0A".  
         "\x16\x17\x18\x19\x1A".  
         "\x25\x26\x27\x28\x29".  
         "\x2A\x34\x35\x36\x37".  
         "\x38\x39\x3A\x43\x44".  
         "\x45\x46\x47\x48\x49".  
         "\x4A\x53\x54\x55\x56".  
         "\x57\x58\x59\x5A\x63".  
         "\x64\x65\x66\x67\x68".  
         "\x69\x6A\x73\x74\x75".  
         "\x76\x77\x78\x79\x7A".  
         "\x83\x84\x85\x86\x87".  
         "\x88\x89\x8A\x92\x93".  
         "\x94\x95\x96\x97\x98".  
         "\x99\x9A\xA2\xA3\xA4".  
         "\xA5\xA6\xA7\xA8\xA9".  
         "\xAA\xB2\xB3\xB4\xB5".  
         "\xB6\xB7\xB8\xB9\xBA".  
         "\xC2\xC3\xC4\xC5\xC6".  
         "\xC7\xC8\xC9\xCA\xD2".  
         "\xD3\xD4\xD5\xD6\xD7".  
         "\xD8\xD9\xDA\xE1\xE2".  
         "\xE3\xE4\xE5\xE6\xE7".  
         "\xE8\xE9\xEA\xF1\xF2".  
         "\xF3\xF4\xF5\xF6\xF7".  
         "\xF8\xF9\xFA".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\x1F".             # Length (31 bytes)  
         "\x01".                 # DC, (byte) table 1  
         "\x00\x03\x01\x01\x01".  
         "\x01\x01\x01\x01\x01".  
         "\x01\x00\x00\x00\x00".  
         "\x00\x00\x01\x02\x03".  
         "\x04\x05\x06\x07\x08".  
         "\x09\x0A\x0B".  
         # Define huffman table (section B.2.4.1)  
         "\xFF\xC4".             # Marker  
         "\x00\xB5".             # Length (181 bytes)  
         "\x11".                 # AC, (byte) table 1  
         "\x00\x02\x01\x02\x04".  
         "\x04\x03\x04\x07\x05".  
         "\x04\x04\x00\x01\x02".  
         "\x77\x00\x01\x02\x03".  
         "\x11\x04\x05\x21\x31".  
         "\x06\x12\x41\x51\x07".  
         "\x61\x71\x13\x22\x32".  
         "\x81\x08\x14\x42\x91".  
         "\xA1\xB1\xC1\x09\x23".  
         "\x33\x52\xF0\x15\x62".  
         "\x72\xD1\x0A\x16\x24".  
         "\x34\xE1\x25\xF1\x17".  
         "\x18\x19\x1A\x26\x27".  
         "\x28\x29\x2A\x35\x36".  
         "\x37\x38\x39\x3A\x43".  
         "\x44\x45\x46\x47\x48".  
         "\x49\x4A\x53\x54\x55".  
         "\x56\x57\x58\x59\x5A".  
         "\x63\x64\x65\x66\x67".  
         "\x68\x69\x6A\x73\x74".  
         "\x75\x76\x77\x78\x79".  
         "\x7A\x82\x83\x84\x85".  
         "\x86\x87\x88\x89\x8A".  
         "\x92\x93\x94\x95\x96".  
         "\x97\x98\x99\x9A\xA2".  
         "\xA3\xA4\xA5\xA6\xA7".  
         "\xA8\xA9\xAA\xB2\xB3".  
         "\xB4\xB5\xB6\xB7\xB8".  
         "\xB9\xBA\xC2\xC3\xC4".  
         "\xC5\xC6\xC7\xC8\xC9".  
         "\xCA\xD2\xD3\xD4\xD5".  
         "\xD6\xD7\xD8\xD9\xDA".  
         "\xE2\xE3\xE4\xE5\xE6".  
         "\xE7\xE8\xE9\xEA\xF2".  
         "\xF3\xF4\xF5\xF6\xF7".  
         "\xF8\xF9\xFA".  
 #------------------------------------------------------------------  
                 "\xFF\xDA".     # Start of Scan marker  
         pack("nC11",  
                 12,                     # length  
                 3,                      # number of components  
                 1,0x00,         # Scan 1: use DC/AC huff tables 0/0  
                 2,0x11,         # Scan 2: use DC/AC huff tables 1/1  
                 3,0x11,         # Scan 3: use DC/AC huff tables 1/1  
                 0,0x3f,         # Ss, Se  
                 0,                      # Ah, Ai (not used)  
         );  
 #------------------------------------------------------------------  
   
         my $header =  
         # SOI  
         "\xFF\xD8".  
         # JFIF  
         "\xFF\xE0".  
         "\x00\x0e\x41\x56\x49\x31\x00\x00\x00\x00\x00\x00\x00\x00".  
         "\xff\xDD\x00\x04\x00\x00".  
         # quantization table  
         "\xFF\xDB".  
         "\x00\x43\x00\x21\x16\x18".  
         "\x1D\x18\x14\x21\x1D\x1B\x1D\x25".  
         "\x23\x21\x27\x31\x53\x36\x31\x2D".  
         "\x2D\x31\x65\x48\x4c\x3c\x53\x78".  
         "\x6a\x7e\x7c\x76\x6a\x74\x72\x85".  
         "\x95\xbf\xa2\x85\x8d\xb4\x8f\x72".  
         "\x74\xa6\xe2\xa8\xb4\xc5\xcb\xd6".  
         "\xd8\xd6\x80\xa0\xeb\xfb\xe8\xd0".  
         "\xf9\xbf\xd2\xd6\xcd".  
         # quantization table  
         "\xff\xdb".  
         "\x00\x43\x01\x23\x25\x25\x31\x2b\x31".  
         "\x61\x36\x36\x61\xcd\x89\x74\x89".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd".  
         "\xcd\xcd".  
300          # Define huffman table (section B.2.4.1)          # Define huffman table (section B.2.4.1)
301          "\xFF\xC4".     # Marker          "\xFF\xC4".     # Marker
302          "\x00\x1F".     # Length (31 bytes)          "\x00\x1F".     # Length (31 bytes)
303          "\x00".         # DC, table 0          "\x00".         # DC luminance, table 0
304          "\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00".          "\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00".
305          "\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07".          "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".
         "\x08\x09\x0A\x0B".  
306          # Define huffman table (section B.2.4.1)          # Define huffman table (section B.2.4.1)
307          "\xFF\xC4".     # Marker          "\xFF\xC4".     # Marker
308          "\x00\xB5".     # Length (181 bytes)          "\x00\xB5".     # Length (181 bytes)
309          "\x10".         # AC, table 0          "\x10".         # AC luminance, table 0
310          "\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04".          "\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01\x7D".
311          "\x00\x00\x01\x7D\x01\x02\x03\x00\x04\x11\x05\x12".          "\x01\x02\x03\x00\x04\x11\x05\x12".
312          "\x21\x31\x41\x06\x13\x51\x61\x07\x22\x71\x14\x32".          "\x21\x31\x41\x06\x13\x51\x61\x07\x22\x71\x14\x32".
313          "\x81\x91\xA1\x08\x23\x42\xB1\xC1\x15\x52\xD1\xF0".          "\x81\x91\xA1\x08\x23\x42\xB1\xC1\x15\x52\xD1\xF0".
314          "\x24\x33\x62\x72\x82\x09\x0A\x16\x17\x18\x19\x1A".          "\x24\x33\x62\x72\x82\x09\x0A\x16\x17\x18\x19\x1A".
# Line 379  sub mkjpg { Line 323  sub mkjpg {
323          "\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA".          "\xD9\xDA\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA".
324          "\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".          "\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".
325          # Define huffman table (section B.2.4.1)          # Define huffman table (section B.2.4.1)
326          "\xFF\xC4".     #       /* Marker */          "\xFF\xC4".     # Marker
327          "\x00\x1F".     #       /* Length (31 bytes) */          "\x00\x1F".     # Length (31 bytes)
328          "\x01".         #/* DC". table 1 */          "\x01".         # DC chrominance, table 1
329          "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00".          "\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00".
330          "\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07".          "\x00\x00\x00\x00".
331          "\x08\x09\x0A\x0B".          "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B".
332          #/* Define huffman table (section B.2.4.1) */          #/* Define huffman table (section B.2.4.1) */
333          "\xFF\xC4".     #       /* Marker */          "\xFF\xC4".     # Marker
334          "\x00\xB5".     #       /* Length (181 bytes) */          "\x00\xB5".     # Length (181 bytes)
335          "\x11".         #/* AC". table 1 */          "\x11".         # AC chrominance, table 1
336          "\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04".          "\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04".
337          "\x00\x01\x02\x77\x00\x01\x02\x03\x11\x04\x05\x21".          "\x00\x01\x02\x77".
338            "\x00\x01\x02\x03\x11\x04\x05\x21".
339          "\x31\x06\x12\x41\x51\x07\x61\x71\x13\x22\x32\x81".          "\x31\x06\x12\x41\x51\x07\x61\x71\x13\x22\x32\x81".
340          "\x08\x14\x42\x91\xA1\xB1\xC1\x09\x23\x33\x52\xF0".          "\x08\x14\x42\x91\xA1\xB1\xC1\x09\x23\x33\x52\xF0".
341          "\x15\x62\x72\xD1\x0A\x16\x24\x34\xE1\x25\xF1\x17".          "\x15\x62\x72\xD1\x0A\x16\x24\x34\xE1\x25\xF1\x17".
# Line 404  sub mkjpg { Line 349  sub mkjpg {
349          "\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6".          "\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xD2\xD3\xD4\xD5\xD6".
350          "\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9".          "\xD7\xD8\xD9\xDA\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9".
351          "\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".          "\xEA\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA".
352          # start of frame          # Start of Scan marker
353          "\xff\xc0".          "\xFF\xDA".
354          "\x00\x11\x08".          pack("nC10",
355          pack("nn", 120, 160).                  12,                     # length
356          "\x03\x01\x21\x00\x02\x11\x01\x03\x11\x01".                  3,                      # number of components
357          #                  1,0x00,         # Scan 1: use DC/AC huff tables 0/0
358          "\xff\xda".                  2,0x11,         # Scan 2: use DC/AC huff tables 1/1
359          "\x00\x0c\x03\x01\x00\x02\x11\x03\x11".                  3,0x11,         # Scan 3: use DC/AC huff tables 1/1
360          "\x00\x3f\x00";                  0,0x3f,         # Ss, Se
361                    0,                      # Ah, Ai (not used)
362            );
363    
364          if ( $dump ) {          if ( $dump_jpeg ) {
365                  warn "## created JPEG header...\n";                  print "## created JPEG header...\n";
366                  hex_dump( $header, 0 );                  hex_dump( $header, 0 );
367          }          }
368    
369          print $fh $header || die "can't write header into $path: $!";          my $frame = join('', @subframes ) . $data;
370          print $fh $data || die "can't write frame into $path: $!";          @subframes = ();
371    
372            my $path = sprintf("$dump_dir/%04d.jpg", $frame_nr );
373    
374            my $fh;
375            if ( $jpegtran ) {
376                    open($fh, '|-', "jpegtran $jpegtran > $path") || die "can't create $path: $!";
377            } else {
378                    open($fh, '>', $path) || die "can't create $path: $!";
379            }
380    
381            if ( ! $no_jpeg_header ) {
382                    print $fh $header . $frame . "\xFF\xD9" || die "can't write jpeg $path: $!";
383            } else {
384                    print $fh $frame || die "can't write raw jpeg $path: $!";
385            }
386          close $fh || die "can't close $path: $!";          close $fh || die "can't close $path: $!";
387          print ">> created $path ", -s $path, " bytes\n";          print ">> created $frame_nr ", $no_jpeg_header ? 'raw' : '', " jpeg $path ", -s $path, " bytes\n" if $verbose;
388  }  }
389    
390  my ( $riff, $amv ) = x(12, 'Z4x4Z4');  my ( $riff, $amv ) = x(12, 'Z4x4Z4');
391  die "$path not RIFF but $riff" if $riff ne 'RIFF';  die "$path not RIFF but $riff" if $riff ne 'RIFF';
392  die "$path not AMV but $amv" if $amv ne 'AMV ';  die "$path not AMV but $amv" if $amv ne 'AMV ';
393    
394    my $apath = "$dump_dir/audio.wav";
395    open(my $audio_fh, '>', $apath) || die "can't open audio file $apath: $!";
396    
397    print $audio_fh pack 'a4Va4a4VvvVVv4', (
398            # header 'RIFF', size
399            'RIFF',-1,
400            # type: 'WAVE'
401            'WAVE',
402            'fmt ',0x14,
403            # format: DVI (IMA) ADPCM Wave Type
404            0x11,
405            # channels
406            1,
407            # samples/sec
408            22050,
409            # avg. bytes/sec (for esimation)
410            11567,
411            # block align (size of block)
412            0x800,
413            # bits per sample (mono data)
414            4,
415            # cbSize (ADPCM with 7 soefficient pairs)
416            2,
417            # nSamplesPerBlock
418            # (((nBlockAlign - (7 * nChannels)) * 8) / (wBitsPerSample * nChannels)) + 2
419            0x0ff9,
420    );
421    
422    print $audio_fh pack 'a4VVa4V', (
423            # time length of the data in samples
424            'fact',4,
425            220500,
426            #
427            'data',-1,
428    );
429    
430    my $riff_header_len = tell($audio_fh);
431    
432  while ( ! defined($d->{eof}) ) {  while ( ! defined($d->{eof}) ) {
433          my ( $list, $name ) = x(12,'A4x4A4');          my ( $list, $name ) = x(12,'A4x4A4');
434          die "not LIST but $list" if $list ne 'LIST';          die "not LIST but $list" if $list ne 'LIST';
435          print "< $list * $name\n";          print "< $list * $name\n" if $verbose;
436    
437          if ( $name eq 'hdrl' ) {          if ( $name eq 'hdrl' ) {
438    
# Line 465  while ( ! defined($d->{eof}) ) { Line 465  while ( ! defined($d->{eof}) ) {
465                                    
466                          my $len = next_part( '00dc' );                          my $len = next_part( '00dc' );
467                          last unless $len;                          last unless $len;
468                          printf "<< %s 00dc - frame %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len;                          printf "<< %s 00dc - part %d jpeg %d 0x%x bytes\n", $name, $frame, $len, $len if $verbose;
469                          mkjpg( sprintf("$dump_dir/%03d.jpg", $frame ), x($len) );                          mkjpg( x($len) );
470    
471                            $len = next_part( '01wb' );
472                            printf "<< %s 01wb - part %d audio %d 0x%x bytes\n", $name, $frame, $len, $len if $verbose;
473    
474                          $len = next_part( '01wb', 0, 1 );                          my $audio_frame = x( $len );
475                          printf "<< %s 01wb - frame %d audio %d 0x%x bytes\n", $name, $frame, $len, $len;  
476                            if ( $dump_audio ) {
477                                    printf "#### dumping audio frame %d 0x%x bytes\n", length($audio_frame), length($audio_frame);
478                                    hex_dump( $audio_frame );
479                            }
480    
481                            # remove 8 bytes of something
482                            $audio_frame = substr( $audio_frame, 8 );
483    
484                            if ( length($audio_frame) % 2 == 0 ) {
485                                    print "#### even sized frame!";
486    #                               $audio_frame = substr( $audio_frame, 0, -1 );
487                            }
488    
489    #                       print $audio_fh mp3_frame;
490                            print $audio_fh $audio_frame || die "can't write audio frame in $apath: $!";
491    
492                            $frame_nr++;
493                  };                  };
494    
495          } else {          } else {
496                  die "unknown $list $name";                  die "unknown $list $name";
497          }          }
498  }  }
499    
500    my $cmd = "ffmpeg -i $dump_dir/%04d.jpg -r 16 -y $dump_avi";
501    system($cmd) == 0 || die "can't convert frames to avi using $cmd: $!";
502    
503    my $size = tell($audio_fh);
504    warn "## wav file size: $size\n";
505    
506    seek( $audio_fh, 4, 0 );
507    print $audio_fh pack("V", $size - 8);
508    seek( $audio_fh, $riff_header_len - 4, 0 );
509    print $audio_fh pack("V", $size - $riff_header_len);
510    
511    close($audio_fh) || die "can't close audio file $apath: $!";
512    
513    print ">>>> created $frame_nr frames $dump_avi ", -s $dump_avi, " and $apath ", -s $apath, "\n";

Legend:
Removed from v.13  
changed lines
  Added in v.27

  ViewVC Help
Powered by ViewVC 1.1.26