1
1
mirror of https://github.com/wader/fq.git synced 2024-11-23 18:56:52 +03:00

Merge pull request #787 from wader/matroska-ebml-date

matroska: Decode ebml date type
This commit is contained in:
Mattias Wadman 2023-10-17 11:31:32 +02:00 committed by GitHub
commit 5b9c902949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 54 additions and 49 deletions

View File

@ -332,7 +332,7 @@ func makeDecodeRecord() func(d *decode.D) {
case dataTypeNumber64F:
d.FieldF64("data")
case dataTypeDate:
d.FieldF64BE("data", scalar.FltActualDate(cocoaTimeEpochDate, time.RFC3339))
d.FieldF64BE("data", scalar.FltActualDateDescription(cocoaTimeEpochDate, time.Second, time.RFC3339))
case dataTypeBooleanFalse:
case dataTypeBooleanTrue:
case dataTypeArray:

View File

@ -130,7 +130,7 @@ func decodeItem(d *decode.D, p *plist) bool {
case elementTypeDate:
n := 1 << decodeSize(d, d.UintAssert(4, 8))
d.FieldValueUint("size", uint64(n))
d.FieldF("value", n*8, scalar.FltActualDate(cocoaTimeEpochDate, time.RFC3339))
d.FieldF("value", n*8, scalar.FltActualDateDescription(cocoaTimeEpochDate, time.Second, time.RFC3339))
case elementTypeData:
n := decodeSize(d)
d.FieldValueUint("size", n)

View File

@ -66,7 +66,7 @@ func decodeBitcoinBlock(d *decode.D) any {
d.FieldU32("version", scalar.UintHex)
d.FieldRawLen("previous_block_hash", 32*8, rawHexReverse)
d.FieldRawLen("merkle_root", 32*8, rawHexReverse)
d.FieldU32("time", scalar.UintActualUnixTime(time.RFC3339))
d.FieldU32("time", scalar.UintActualUnixTimeDescription(time.Second, time.RFC3339))
d.FieldU32("bits", scalar.UintHex)
d.FieldU32("nonce", scalar.UintHex)
})

View File

@ -76,7 +76,7 @@ func gzDecode(d *decode.D) any {
hasComment = d.FieldBool("comment")
d.FieldU3("reserved")
})
d.FieldU32("mtime", scalar.UintActualUnixTime(time.RFC3339))
d.FieldU32("mtime", scalar.UintActualUnixTimeDescription(time.Second, time.RFC3339))
switch compressionMethod {
case deflateMethod:
d.FieldU8("extra_flags", deflateExtraFlagsNames)

View File

@ -1,5 +1,10 @@
package ebml
import "time"
// 2001-01-01T00:00:00.000000000 UTC
var EpochDate = time.Date(2001, time.January, 1, 0, 0, 0, 0, time.UTC)
type ID int
type Element interface {

View File

@ -14,6 +14,7 @@ package matroska
import (
"embed"
"fmt"
"time"
"github.com/wader/fq/format"
"github.com/wader/fq/format/matroska/ebml"
@ -117,6 +118,8 @@ var lacingTypeNames = scalar.UintMapSymStr{
const tagSizeUnknown = 0xffffffffffffff
var sintActualMatroskaEpochDescription = scalar.SintActualDateDescription(ebml.EpochDate, time.Nanosecond, time.RFC3339)
func decodeLacingFn(d *decode.D, lacingType int, fn func(d *decode.D)) {
if lacingType == lacingTypeNone {
fn(d)
@ -383,28 +386,14 @@ func decodeMaster(d *decode.D, bitsLimit int64, elm *ebml.Master, unknownSize bo
case *ebml.UTF8:
d.FieldUTF8NullFixedLen("value", int(tagSize))
case *ebml.Date:
// TODO:
/*
proc type_date {size label _extra} {
set s [clock scan {2001-01-01 00:00:00}]
set frac 0
switch $size {
0 {}
8 {
set nano [int64]
set s [clock add $s [expr $nano/1000000000] seconds]
set frac [expr ($nano%1000000000)/1000000000.0]
}
default {
bytes $size $label
return
}
}
entry $label "[clock format $s] ${frac}s" $size [expr [pos]-$size]
}
*/
d.FieldRawLen("value", int64(tagSize)*8)
switch tagSize {
case 0:
d.FieldValueSint("value", 0, sintActualMatroskaEpochDescription)
case 8:
d.FieldS("value", int(tagSize)*8, sintActualMatroskaEpochDescription)
default:
d.FieldRawLen("value", int64(tagSize)*8)
}
case *ebml.Binary:
switch tagID {
case ebml_matroska.SimpleBlockID:

View File

@ -159,7 +159,7 @@ $ fq dv sweep-with-DC.mkvmerge13.mka
0x10a0| 44 61 | Da | id: "date_utc" (0x4461) (The date and time that the Segment was created by the muxing application or library) 0x10a5-0x10a6.7 (2)
| | | type: "date"
0x10a0| 88 | . | size: 8 0x10a7-0x10a7.7 (1)
0x10a0| 09 7b f0 a0 97 43 d2 00| .{...C..| value: raw bits 0x10a8-0x10af.7 (8)
0x10a0| 09 7b f0 a0 97 43 d2 00| .{...C..| value: 683404341000000000 (2022-08-28T18:32:21Z) 0x10a8-0x10af.7 (8)
| | | [5]{}: element 0x10b0-0x10c2.7 (19)
0x10b0|73 a4 |s. | id: "segment_uuid" (0x73a4) (A randomly generated unique ID to identify the Segment amongst many others chosen) 0x10b0-0x10b1.7 (2)
| | | type: "binary"

View File

@ -207,7 +207,7 @@ func decodeLang(d *decode.D) string {
// Quicktime time seconds in January 1, 1904 UTC
var quicktimeEpochDate = time.Date(1904, time.January, 1, 0, 0, 0, 0, time.UTC)
var uintActualQuicktimeEpoch = scalar.UintActualDate(quicktimeEpochDate, time.RFC3339)
var uintActualQuicktimeEpochDescription = scalar.UintActualDateDescription(quicktimeEpochDate, time.Second, time.RFC3339)
func decodeMvhdFieldMatrix(d *decode.D, name string) {
d.FieldStruct(name, func(d *decode.D) {
@ -398,13 +398,13 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
d.FieldU24("flags")
switch version {
case 0:
d.FieldU32("creation_time", uintActualQuicktimeEpoch)
d.FieldU32("modification_time", uintActualQuicktimeEpoch)
d.FieldU32("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU32("modification_time", uintActualQuicktimeEpochDescription)
d.FieldU32("time_scale")
d.FieldU32("duration")
case 1:
d.FieldU64("creation_time", uintActualQuicktimeEpoch)
d.FieldU64("modification_time", uintActualQuicktimeEpoch)
d.FieldU64("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU64("modification_time", uintActualQuicktimeEpochDescription)
d.FieldU32("time_scale")
d.FieldU64("duration")
default:
@ -458,14 +458,14 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
})
switch version {
case 0:
d.FieldU32("creation_time", uintActualQuicktimeEpoch)
d.FieldU32("modification_time", uintActualQuicktimeEpoch)
d.FieldU32("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU32("modification_time", uintActualQuicktimeEpochDescription)
trackID = int(d.FieldU32("track_id"))
d.FieldU32("reserved1")
d.FieldU32("duration")
case 1:
d.FieldU64("creation_time", uintActualQuicktimeEpoch)
d.FieldU64("modification_time", uintActualQuicktimeEpoch)
d.FieldU64("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU64("modification_time", uintActualQuicktimeEpochDescription)
trackID = int(d.FieldU32("track_id"))
d.FieldU32("reserved1")
d.FieldU64("duration")
@ -493,13 +493,13 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
// TODO: timestamps
switch version {
case 0:
d.FieldU32("creation_time", uintActualQuicktimeEpoch)
d.FieldU32("modification_time", uintActualQuicktimeEpoch)
d.FieldU32("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU32("modification_time", uintActualQuicktimeEpochDescription)
d.FieldU32("time_scale")
d.FieldU32("duration")
case 1:
d.FieldU64("creation_time", uintActualQuicktimeEpoch)
d.FieldU64("modification_time", uintActualQuicktimeEpoch)
d.FieldU64("creation_time", uintActualQuicktimeEpochDescription)
d.FieldU64("modification_time", uintActualQuicktimeEpochDescription)
d.FieldU32("time_scale")
d.FieldU64("duration")
default:

View File

@ -316,7 +316,7 @@ func decodeTLSHandshake(d *decode.D, tc *tlsCtx) {
tc.version = d.FieldU16("version", versionNames, scalar.UintHex)
copy(tc.random[:], d.PeekBytes(32))
d.FieldStruct("random", func(d *decode.D) {
d.FieldU32("gmt_unix_time", scalar.UintActualUnixTime(time.RFC3339))
d.FieldU32("gmt_unix_time", scalar.UintActualUnixTimeDescription(time.Second, time.RFC3339))
d.FieldRawLen("random_bytes", 28*8)
})

View File

@ -246,24 +246,35 @@ func (m RawBytesMap) MapBitBuf(s BitBuf) (BitBuf, error) {
var unixTimeEpochDate = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
func UintActualDate(epoch time.Time, format string) UintFn {
func UintActualDateDescription(epoch time.Time, unit time.Duration, format string) UintFn {
return UintFn(func(s Uint) (Uint, error) {
s.Description = epoch.Add(time.Duration(s.Actual) * time.Second).Format(format)
s.Description = epoch.Add(time.Duration(s.Actual) * unit).Format(format)
return s, nil
})
}
func UintActualUnixTime(format string) UintFn {
return UintActualDate(unixTimeEpochDate, format)
func UintActualUnixTimeDescription(unit time.Duration, format string) UintFn {
return UintActualDateDescription(unixTimeEpochDate, unit, format)
}
func FltActualDate(epoch time.Time, format string) FltFn {
func SintActualDateDescription(epoch time.Time, unit time.Duration, format string) SintFn {
return SintFn(func(s Sint) (Sint, error) {
s.Description = epoch.Add(time.Duration(s.Actual) * unit).Format(format)
return s, nil
})
}
func SintActualUnixTimeDescription(unit time.Duration, format string) SintFn {
return SintActualDateDescription(unixTimeEpochDate, unit, format)
}
func FltActualDateDescription(epoch time.Time, unit time.Duration, format string) FltFn {
return FltFn(func(s Flt) (Flt, error) {
s.Description = epoch.Add(time.Duration(s.Actual) * time.Second).Format(format)
s.Description = epoch.Add(time.Duration(s.Actual) * unit).Format(format)
return s, nil
})
}
func FltActualUnixTime(format string) FltFn {
return FltActualDate(unixTimeEpochDate, format)
func FltActualUnixTimeDescription(unit time.Duration, format string) FltFn {
return FltActualDateDescription(unixTimeEpochDate, unit, format)
}