summaryrefslogtreecommitdiff
path: root/lib/Image/ExifTool/QuickTimeStream.pl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Image/ExifTool/QuickTimeStream.pl')
-rw-r--r--lib/Image/ExifTool/QuickTimeStream.pl85
1 files changed, 81 insertions, 4 deletions
diff --git a/lib/Image/ExifTool/QuickTimeStream.pl b/lib/Image/ExifTool/QuickTimeStream.pl
index 1fd7cfac..c9b268bb 100644
--- a/lib/Image/ExifTool/QuickTimeStream.pl
+++ b/lib/Image/ExifTool/QuickTimeStream.pl
@@ -71,13 +71,17 @@ my $mpsToKph = 3.6; # m/s --> km/h
GPSTrackRef => { PrintConv => { M => 'Magnetic North', T => 'True North' } },
GPSDateTime => { PrintConv => '$self->ConvertDateTime($val)', Groups => { 2 => 'Time' } },
Accelerometer=> { Notes => 'right/up/backward acceleration in units of g' },
+ RawGSensor => {
+ # (same as GSensor, but offset by some unknown value)
+ ValueConv => 'my @a=split " ",$val; $_/=1000 foreach @a; "@a"',
+ },
Text => { Groups => { 2 => 'Other' } },
TimeCode => { Groups => { 2 => 'Video' } },
FrameNumber => { Groups => { 2 => 'Video' } },
SampleTime => { Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)', Notes => 'sample decoding time' },
SampleDuration=>{ Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)' },
#
-# timed metadata decoded based on MetaFormat (format of 'meta' sample description)
+# timed metadata decoded based on MetaFormat (format of 'meta' or 'data' sample description)
# [or HandlerType, or specific 'vide' type if specified]
#
mebx => {
@@ -105,6 +109,22 @@ my $mpsToKph = 3.6; # m/s --> km/h
Name => 'CTMD',
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CTMD' },
},
+ RVMI => [{ # data "OtherFormat" written by E-PRANCE B47FS editing app
+ Name => 'RVMI_g',
+ Condition => '$$valPt =~ /^gReV/', # GPS data
+ SubDirectory => {
+ TagTable => 'Image::ExifTool::QuickTime::RVMI_g',
+ ByteOrder => 'Little-endian',
+ },
+ },{
+ Name => 'RVMI_s',
+ Condition => '$$valPt =~ /^sReV/', # sensor data?
+ SubDirectory => {
+ TagTable => 'Image::ExifTool::QuickTime::RVMI_s',
+ ByteOrder => 'Little-endian',
+ },
+ # (there is also "tReV" data that hasn't been decoded yet)
+ }],
camm => { # (written by Insta360) - [HandlerType, not MetaFormat]
Name => 'camm6',
Condition => '$$valPt =~ /^\0\0\x06\0/',
@@ -150,6 +170,48 @@ my $mpsToKph = 3.6; # m/s --> km/h
# 0x30 - float (GPSSpeed?)
);
+# tags found in 'RVMI' 'gReV' timed metadata (ref PH)
+%Image::ExifTool::QuickTime::RVMI_g = (
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+ GROUPS => { 2 => 'Location' },
+ FIRST_ENTRY => 0,
+ 4 => {
+ Name => 'GPSLatitude',
+ Format => 'int32s',
+ ValueConv => 'Image::ExifTool::GPS::ToDegrees($val/1e6, 1)',
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+ },
+ 8 => {
+ Name => 'GPSLongitude',
+ Format => 'int32s',
+ ValueConv => 'Image::ExifTool::GPS::ToDegrees($val/1e6, 1)',
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+ },
+ # 12 - int32s: space for altitude? (always zero in my sample)
+ 16 => {
+ Name => 'GPSSpeed', # km/h
+ Format => 'int16s',
+ ValueConv => '$val / 10',
+ },
+ 18 => {
+ Name => 'GPSTrack',
+ Format => 'int16u',
+ ValueConv => '$val * 2',
+ },
+);
+
+# tags found in 'RVMI' 'sReV' timed metadata (ref PH)
+%Image::ExifTool::QuickTime::RVMI_s = (
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+ GROUPS => { 2 => 'Location' },
+ FIRST_ENTRY => 0,
+ 4 => {
+ Name => 'GSensor',
+ Format => 'int16s[3]', # X Y Z
+ ValueConv => 'my @a=split " ",$val; $_/=1000 foreach @a; "@a"',
+ },
+);
+
#------------------------------------------------------------------------------
# Save information from keys in OtherSampleDesc directory for processing timed metadata
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -376,8 +438,23 @@ sub ProcessSamples($)
next if $size == 2;
$buff = substr($buff,2);
}
- $et->HandleTag($tagTbl, Text => $buff);
- next;
+ my $val;
+ # check for encrypted GPS text as written by E-PRANCE B47FS camera
+ if ($buff =~ /^\0/ and $buff =~ /\x0a$/ and length($buff) > 5) {
+ # decode simple ASCII difference cipher,
+ # based on known value of 4th-last char = '*'
+ my $dif = ord('*') - ord(substr($buff, -4, 1));
+ my $tmp = pack 'C*',map { $_=($_+$dif)&0xff } unpack 'C*',substr $buff,1,-1;
+ if ($tmp =~ /^(.*?)(\$GPRMC.*)/s) {
+ ($val, $buff) = ($1, $2);
+ $val =~ tr/\t/ /;
+ $et->HandleTag($tagTbl, RawGSensor => $val) if length $val;
+ }
+ }
+ unless (defined $val) {
+ $et->HandleTag($tagTbl, Text => $buff); # just store any other text
+ next;
+ }
}
while ($buff =~ /\$(\w+)([^\$]*)/g) {
my ($tag, $dat) = ($1, $2);
@@ -406,7 +483,7 @@ sub ProcessSamples($)
}
}
- } elsif ($type eq 'meta') {
+ } elsif ($type eq 'meta' or $type eq 'data') {
if ($$tagTbl{$metaFormat}) {
my $tagInfo = $et->GetTagInfo($tagTbl, $metaFormat, \$buff);