"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/Image/ExifTool/QuickTimeStream.pl" between
Image-ExifTool-12.26.tar.gz and Image-ExifTool-12.27.tar.gz

About: ExifTool is a platform-independent Perl library plus a command-line application for reading, writing and editing meta information in a wide variety of files.

QuickTimeStream.pl  (Image-ExifTool-12.26):QuickTimeStream.pl  (Image-ExifTool-12.27)
skipping to change at line 98 skipping to change at line 98
# limit the default amount of data we read for some record types # limit the default amount of data we read for some record types
# (to avoid running out of memory) # (to avoid running out of memory)
my %insvLimit = ( my %insvLimit = (
0x300 => [ 'accelerometer', 20000 ], # maximum of 20000 accelerometer rec ords 0x300 => [ 'accelerometer', 20000 ], # maximum of 20000 accelerometer rec ords
); );
# tags extracted from various QuickTime data streams # tags extracted from various QuickTime data streams
%Image::ExifTool::QuickTime::Stream = ( %Image::ExifTool::QuickTime::Stream = (
GROUPS => { 2 => 'Location' }, GROUPS => { 2 => 'Location' },
NOTES => q{ NOTES => q{
Timed metadata extracted from QuickTime media data and some AVI videos w The tags below are extracted from timed metadata in QuickTime and other
hen formats of video files when the ExtractEmbedded option is used. Althoug
the ExtractEmbedded option is used. Although most of these tags are h
combined into the single table below, ExifTool currently reads 51 differ most of these tags are combined into the single table below, ExifTool
ent currently reads 53 different formats of timed GPS metadata from video fi
formats of timed GPS metadata from video files. les.
}, },
VARS => { NO_ID => 1 }, VARS => { NO_ID => 1 },
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' }, GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' }, GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
GPSAltitude => { PrintConv => '(sprintf("%.4f", $val) + 0) . " m"' }, # rou nd to 4 decimals GPSAltitude => { PrintConv => '(sprintf("%.4f", $val) + 0) . " m"' }, # rou nd to 4 decimals
GPSSpeed => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals GPSSpeed => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals
GPSSpeedRef => { PrintConv => { K => 'km/h', M => 'mph', N => 'knots' } }, GPSSpeedRef => { PrintConv => { K => 'km/h', M => 'mph', N => 'knots' } },
GPSTrack => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals GPSTrack => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals
GPSTrackRef => { PrintConv => { M => 'Magnetic North', T => 'True North' } }, GPSTrackRef => { PrintConv => { M => 'Magnetic North', T => 'True North' } },
GPSDateTime => { GPSDateTime => {
skipping to change at line 171 skipping to change at line 171
# [or HandlerType, or specific 'vide' type if specified] # [or HandlerType, or specific 'vide' type if specified]
# #
mebx => { mebx => {
Name => 'mebx', Name => 'mebx',
SubDirectory => { SubDirectory => {
TagTable => 'Image::ExifTool::QuickTime::Keys', TagTable => 'Image::ExifTool::QuickTime::Keys',
ProcessProc => \&Process_mebx, ProcessProc => \&Process_mebx,
}, },
}, },
gpmd => [{ gpmd => [{
Name => 'gpmd_GoPro', Name => 'gpmd_Kingslim', # Kingslim D4 dashcam
Condition => '$$valPt !~ /^\0\0\xf2\xe1\xf0\xeeTT/', Condition => '$$valPt =~ /^.{21}\0\0\0A[NS][EW]/s',
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' }, SubDirectory => {
TagTable => 'Image::ExifTool::QuickTime::Stream',
ProcessProc => \&ProcessFreeGPS,
},
},{ },{
Name => 'gpmd_Rove', # Rove Stealth 4K encrypted text Name => 'gpmd_Rove', # Rove Stealth 4K encrypted text
Condition => '$$valPt =~ /^\0\0\xf2\xe1\xf0\xeeTT/',
SubDirectory => { SubDirectory => {
TagTable => 'Image::ExifTool::QuickTime::Stream', TagTable => 'Image::ExifTool::QuickTime::Stream',
ProcessProc => \&Process_text, ProcessProc => \&Process_text,
}, },
},{
Name => 'gpmd_GoPro',
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
}], }],
fdsc => { fdsc => {
Name => 'fdsc', Name => 'fdsc',
Condition => '$$valPt =~ /^GPRO/', Condition => '$$valPt =~ /^GPRO/',
# (other types of "fdsc" samples aren't yet parsed: /^GP\x00/ and /^GP\x 04/) # (other types of "fdsc" samples aren't yet parsed: /^GP\x00/ and /^GP\x 04/)
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::fdsc' }, SubDirectory => { TagTable => 'Image::ExifTool::GoPro::fdsc' },
}, },
rtmd => { rtmd => {
Name => 'rtmd', Name => 'rtmd',
SubDirectory => { TagTable => 'Image::ExifTool::Sony::rtmd' }, SubDirectory => { TagTable => 'Image::ExifTool::Sony::rtmd' },
skipping to change at line 411 skipping to change at line 418
%Image::ExifTool::QuickTime::camm6 = ( %Image::ExifTool::QuickTime::camm6 = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
GROUPS => { 2 => 'Location' }, GROUPS => { 2 => 'Location' },
FIRST_ENTRY => 0, FIRST_ENTRY => 0,
0x04 => { 0x04 => {
Name => 'GPSDateTime', Name => 'GPSDateTime',
Description => 'GPS Date/Time', Description => 'GPS Date/Time',
Groups => { 2 => 'Time' }, Groups => { 2 => 'Time' },
Format => 'double', Format => 'double',
RawConv => '$$self{FoundGPSDateTime} = 1; $val', RawConv => '$$self{FoundGPSDateTime} = 1; $val',
# by the specification, this should use the GPS epoch of Jan 6, 1980,
# but I have samples which use the Unix epoch of Jan 1, 1970, so convert
# to the Unix Epoch only if it doesn't match the CreateDate within 5 yea
rs
ValueConv => q{ ValueConv => q{
my $offset = 315964800;
if ($$self{CreateDate} and $$self{CreateDate} - $val > 24 * 3600 * 3
65 * 5) {
$val += $offset;
}
my $str = ConvertUnixTime($val); my $str = ConvertUnixTime($val);
my $frac = $val - int($val); my $frac = $val - int($val);
if ($frac != 0) { if ($frac != 0) {
$frac = sprintf('%.6f', $frac); $frac = sprintf('%.6f', $frac);
$frac =~ s/^0//; $frac =~ s/^0//;
$frac =~ s/0+$//; $frac =~ s/0+$//;
$str .= $frac; $str .= $frac;
} }
return $str . 'Z'; return $str . 'Z';
}, },
skipping to change at line 1429 skipping to change at line 1443
unshift @xtra, GPSSatellites => $9; unshift @xtra, GPSSatellites => $9;
unshift @xtra, GPSDOP => $10; unshift @xtra, GPSDOP => $10;
} }
if (defined $lat) { if (defined $lat) {
# extract accelerometer readings if GPS was valid # extract accelerometer readings if GPS was valid
@acc = unpack('x68V3', $$dataPt); @acc = unpack('x68V3', $$dataPt);
# change to signed integer and divide by 256 # change to signed integer and divide by 256
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc; map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
} }
} elsif ($$dataPt =~ /^.{40}A([NS])([EW])/s) { } elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
# decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format ) # decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format )
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ... .] # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ... .]
# 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../.......... .] # 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../.......... .]
# 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%.. E] # 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%.. E]
# 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A... .] # 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A... .]
($latRef, $lonRef) = ($1, $2); ($latRef, $lonRef) = ($1, $2);
($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt); ($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt);
$yr += 2000; $yr += 2000;
SetByteOrder('II'); SetByteOrder('II');
$lat = GetFloat($dataPt, 0x2c); $lat = GetFloat($dataPt, 0x2c);
$lon = GetFloat($dataPt, 0x30); $lon = GetFloat($dataPt, 0x30);
$spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h) $spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h)
$trk = GetFloat($dataPt, 0x38); $trk = GetFloat($dataPt, 0x38);
SetByteOrder('MM'); SetByteOrder('MM');
} elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
# also decode 'gpmd' chunk from Kingslim D4 dashcam videos
# 0000: 0a 00 00 00 0b 00 00 00 07 00 00 00 e5 07 00 00 [...............
.]
# 0010: 06 00 00 00 03 00 00 00 41 4e 57 31 91 52 83 45 [........ANW1.R.
E]
# 0020: 15 70 fe c5 29 5c c3 41 ae c7 af 42 00 00 d1 be [.p..)\.A...B...
.]
# 0030: 00 00 80 3b 00 00 2c 3e 00 00 00 00 00 00 00 00 [...;..,>.......
.]
# 0040: 00 00 00 00 00 00 00 00 00 00 00 00 26 26 26 26 [............&&&
&]
# 0050: 4c 49 47 4f 47 50 53 49 4e 46 4f 00 00 00 00 05 [LIGOGPSINFO....
.]
# 0060: 01 00 00 00 23 23 23 23 75 00 00 00 c0 22 20 20 [....####u...."
]
# 0070: 20 f0 12 10 12 21 e5 0e 10 12 2f 90 10 13 01 f2 [ ....!..../....
.]
($latRef, $lonRef) = ($1, $2);
($hr,$min,$sec,$yr,$mon,$day) = unpack("V6", $$dataPt);
SetByteOrder('II');
# lat/lon aren't decoded properly, but spd,trk,acc are
$lat = GetFloat($dataPt, 0x1c);
$lon = GetFloat($dataPt, 0x20);
$et->VPrint(0, sprintf("Raw lat/lon = %.9f %.9f\n", $lat, $lon));
$et->WarnOnce('GPSLatitude/Longitude encoding is not yet known, so these
will be wrong');
$lat = abs $lat;
$lon = abs $lon;
$spd = GetFloat($dataPt, 0x24) * $knotsToKph; # (convert knots to km/h)
$trk = GetFloat($dataPt, 0x28);
$acc[0] = GetFloat($dataPt, 0x2c);
$acc[1] = GetFloat($dataPt, 0x30);
$acc[2] = GetFloat($dataPt, 0x34);
SetByteOrder('MM');
} elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) { } elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) {
# decode freeGPS from Akaso dashcam # decode freeGPS from Akaso dashcam
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `.. .] # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `.. .]
# 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx........... .] # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx........... .]
# 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000.......... .] # 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000.......... .]
# 0030: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A.. .] # 0030: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A.. .]
# 0040: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE.. .] # 0040: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE.. .]
# 0050: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B....... .] # 0050: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B....... .]
# 0060: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [............... .] # 0060: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [............... .]
skipping to change at line 1807 skipping to change at line 1849
# 0060: 19 00 00 00 06 00 00 00 05 00 00 00 f6 ff ff ff [.............. ..] # 0060: 19 00 00 00 06 00 00 00 05 00 00 00 f6 ff ff ff [.............. ..]
# 0070: 03 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 [.............. ..] # 0070: 03 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 [.............. ..]
($latRef, $lonRef) = ($1, $2); ($latRef, $lonRef) = ($1, $2);
($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x28V6',$$dataPt); ($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x28V6',$$dataPt);
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC ) map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC )
$lat = GetFloat($dataPt, 0x40); $lat = GetFloat($dataPt, 0x40);
$lon = GetFloat($dataPt, 0x48); $lon = GetFloat($dataPt, 0x48);
$spd = GetFloat($dataPt, 0x50); $spd = GetFloat($dataPt, 0x50);
$trk = GetFloat($dataPt, 0x54); $trk = GetFloat($dataPt, 0x54);
} elsif ($$dataPt =~ /^.{16}A([NS])([EW])\0/s) {
# INNOVV MP4 video (same format as INNOVV TS)
while ($$dataPt =~ /(A[NS][EW]\0.{28})/g) {
my $dat = $1;
$lat = abs(GetFloat(\$dat, 4)); # (abs just to be safe)
$lon = abs(GetFloat(\$dat, 8)); # (abs just to be safe)
$spd = GetFloat(\$dat, 12) * $knotsToKph;
$trk = GetFloat(\$dat, 16);
@acc = unpack('x20V3', $dat);
map { $_ = $_ - 4294967296 if $_ >= 0x80000000 } @acc;
my $deg = int($lat / 100);
$lat = $deg + ($lat - $deg * 100) / 60;
$deg = int($lon / 100);
$lon = $deg + ($lon - $deg * 100) / 60;
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
$et->HandleTag($tagTbl, GPSLatitude => $lat * (substr($dat,1,1) eq
'S' ? -1 : 1));
$et->HandleTag($tagTbl, GPSLongitude => $lon * (substr($dat,2,1) eq
'W' ? -1 : 1));
$et->HandleTag($tagTbl, GPSSpeed => $spd);
$et->HandleTag($tagTbl, GPSSpeedRef => 'K');
$et->HandleTag($tagTbl, GPSTrack => $trk);
$et->HandleTag($tagTbl, GPSTrackRef => 'T');
$et->HandleTag($tagTbl, Accelerometer => "@acc");
}
return 1;
} else { } else {
# (look for binary GPS as stored by NextBase 512G, ref PH) # (look for binary GPS as stored by NextBase 512G, ref PH)
# header looks like this in my sample: # header looks like this in my sample:
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x. ..] # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x. ..]
# 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx.......... ..] # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx.......... ..]
# 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000......... ..] # 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000......... ..]
# followed by a number of 32-byte records in this format (big endian!): # followed by a number of 32-byte records in this format (big endian!):
# 0x30 - int16u unknown (seen: 0x24 0x53 = "$S") # 0x30 - int16u unknown (seen: 0x24 0x53 = "$S")
skipping to change at line 1965 skipping to change at line 2033
} }
$$et{HandlerType} = $tag; # fake handler type $$et{HandlerType} = $tag; # fake handler type
ProcessSamples($et); # we have all we need to process sample data now ProcessSamples($et); # we have all we need to process sample data now
} elsif ($tag eq 'GPS ') { } elsif ($tag eq 'GPS ') {
my $pos = 0; my $pos = 0;
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
SetByteOrder('II'); SetByteOrder('II');
while ($pos + 36 < $dataLen) { while ($pos + 36 < $dataLen) {
my $dat = substr($$dataPt, $pos, 36); my $dat = substr($$dataPt, $pos, 36);
last if $dat eq "\x0" x 36; last if $dat eq "\x0" x 36;
my @a = unpack 'VVVVCVCV', $dat; my @a = unpack 'VVVVaVaV', $dat;
$$et{DOC_NUM} = ++$$et{DOC_COUNT}; $$et{DOC_NUM} = ++$$et{DOC_COUNT};
# 0=1, 1=1, 2=secs, 3=? # 0=1, 1=1, 2=secs, 3=?
SetGPSDateTime($et, $tagTbl, $a[2]); SetGPSDateTime($et, $tagTbl, $a[2]);
my $lat = $a[5] / 1e3; my $lat = $a[5] / 1e3;
my $lon = $a[7] / 1e3; my $lon = $a[7] / 1e3;
my $deg = int($lat / 100); my $deg = int($lat / 100);
$lat = $deg + ($lat - $deg * 100) / 60; $lat = $deg + ($lat - $deg * 100) / 60;
$deg = int($lon / 100); $deg = int($lon / 100);
$lon = $deg + ($lon - $deg * 100) / 60; $lon = $deg + ($lon - $deg * 100) / 60;
$lat = -$lat if $a[4] eq 'S'; $lat = -$lat if $a[4] eq 'S';
skipping to change at line 2723 skipping to change at line 2791
$et->VerboseDir('GPS', undef, $len); $et->VerboseDir('GPS', undef, $len);
$et->VerboseDump(\$buff, DataPos => $pos + $dataPos); $et->VerboseDump(\$buff, DataPos => $pos + $dataPos);
} }
my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len }; my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len };
ProcessFreeGPS2($et, $dirInfo, $tagTbl); ProcessFreeGPS2($et, $dirInfo, $tagTbl);
} }
$pos += $len; $pos += $len;
$buf2 = substr($buff, $len); $buf2 = substr($buff, $len);
} }
if ($tagTbl) { if ($tagTbl) {
$$et{DOC_NUM} = 0; $$et{DOC_NUM} = 0; # reset DOC_NUM after extracting embedded metadata
$et->VPrint(0, "--------------------------\n"); $et->VPrint(0, "--------------------------\n");
SetByteOrder($oldByteOrder); SetByteOrder($oldByteOrder);
$$et{INDENT} = substr $$et{INDENT}, 0, -2; $$et{INDENT} = substr $$et{INDENT}, 0, -2;
} }
# process Insta360 trailer if it exists # process Insta360 trailer if it exists
ProcessInsta360($et); ProcessInsta360($et);
} }
1; # end 1; # end
 End of changes. 11 change blocks. 
12 lines changed or deleted 93 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)