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

mp4: add pssh_playready format

This commit is contained in:
Mattias Wadman 2021-09-02 13:08:26 +02:00
parent 10d7ed7806
commit c7d45ff1e0
6 changed files with 118 additions and 0 deletions

View File

@ -67,6 +67,7 @@ const (
PNG = "png"
PROTOBUF = "protobuf"
PROTOBUF_WIDEVINE = "protobuf_widevine"
PSSH_PLAYREADY = "pssh_playready"
TAR = "tar"
TIFF = "tiff"
VORBIS_COMMENT = "vorbis_comment"

View File

@ -995,6 +995,8 @@ func init() {
switch {
case bytes.Equal(systemID, systemIDWidevine[:]):
d.FieldFormatLen("data", int64(dataLen)*8, protoBufWidevineFormat)
case bytes.Equal(systemID, systemIDPlayReady[:]):
d.FieldFormatLen("data", int64(dataLen)*8, psshPlayreadyFormat)
case systemID == nil:
fallthrough
default:

View File

@ -48,6 +48,7 @@ var mpegHEVCSampleFormat []*decode.Format
var mpegPESPacketSampleFormat []*decode.Format
var opusPacketFrameFormat []*decode.Format
var protoBufWidevineFormat []*decode.Format
var psshPlayreadyFormat []*decode.Format
var vorbisPacketFormat []*decode.Format
var vp9FrameFormat []*decode.Format
var vpxCCRFormat []*decode.Format
@ -76,6 +77,7 @@ func init() {
{Names: []string{format.MPEG_PES_PACKET}, Formats: &mpegPESPacketSampleFormat},
{Names: []string{format.OPUS_PACKET}, Formats: &opusPacketFrameFormat},
{Names: []string{format.PROTOBUF_WIDEVINE}, Formats: &protoBufWidevineFormat},
{Names: []string{format.PSSH_PLAYREADY}, Formats: &psshPlayreadyFormat},
{Names: []string{format.VORBIS_PACKET}, Formats: &vorbisPacketFormat},
{Names: []string{format.VP9_FRAME}, Formats: &vp9FrameFormat},
{Names: []string{format.VPX_CCR}, Formats: &vpxCCRFormat},

View File

@ -0,0 +1,46 @@
package mp4
import (
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/pkg/decode"
)
func init() {
registry.MustRegister(&decode.Format{
Name: format.PSSH_PLAYREADY,
Description: "PlayReady PSSH",
DecodeFn: playreadyPsshDecode,
})
}
const (
recordTypeRightsManagementHeader = 1
recordTypeLicenseStore = 2
)
var recordTypeNames = map[uint64]string{
recordTypeRightsManagementHeader: "Rights management header",
recordTypeLicenseStore: "License store",
}
func playreadyPsshDecode(d *decode.D, in interface{}) interface{} {
d.Endian = decode.LittleEndian
d.FieldU32("size")
count := d.FieldU16("count")
i := uint64(0)
d.FieldStructArrayLoopFn("records", "record", func() bool { return i < count }, func(d *decode.D) {
recordType, _ := d.FieldStringMapFn("type", recordTypeNames, "Unknown", d.U16, decode.NumberDecimal)
recordLen := d.FieldU16("len")
switch recordType {
case recordTypeRightsManagementHeader, recordTypeLicenseStore:
d.FieldUTF16LE("xml", int(recordLen))
default:
d.FieldBitBufLen("data", int64(recordLen)*8)
}
i++
})
return nil
}

View File

@ -16,6 +16,32 @@ func (d *D) TryUTF8(nBytes int) (string, error) {
return string(s), nil
}
func (d *D) TryUTF16BE(nBytes int) (string, error) {
b, err := d.bitBuf.BytesLen(nBytes)
// TODO: len check
rs := make([]rune, len(b)/2)
for i := 0; i < len(b)/2; i++ {
rs[i] = rune(uint(b[i*2])<<8 + uint(b[i*2+1]))
}
if err != nil {
return "", err
}
return string(rs), nil
}
func (d *D) TryUTF16LE(nBytes int) (string, error) {
b, err := d.bitBuf.BytesLen(nBytes)
// TODO: len check
rs := make([]rune, len(b)/2)
for i := 0; i < len(b)/2; i++ {
rs[i] = rune(uint(b[i*2]) | uint(b[i*2+1])<<8)
}
if err != nil {
return "", err
}
return string(rs), nil
}
// TryUTF8ShortString read pascal short string, max nBytes
func (d *D) TryUTF8ShortString(nBytes int) (string, error) {
l, err := d.TryU8()
@ -219,6 +245,24 @@ func (d *D) UTF8(nBytes int) string {
return s
}
// UTF16BE read nBytes utf16be string
func (d *D) UTF16BE(nBytes int) string {
s, err := d.TryUTF16BE(nBytes)
if err != nil {
panic(IOError{Err: err, Op: "UTF16BE", Size: int64(nBytes) * 8, Pos: d.Pos()})
}
return s
}
// UTF16LE read nBytes utf16le string
func (d *D) UTF16LE(nBytes int) string {
s, err := d.TryUTF16LE(nBytes)
if err != nil {
panic(IOError{Err: err, Op: "UTF16LE", Size: int64(nBytes) * 8, Pos: d.Pos()})
}
return s
}
// FieldUTF8 read nBytes utf8 string and add a field
func (d *D) FieldUTF8(name string, nBytes int) string {
return d.FieldStrFn(name, func() (string, string) {
@ -230,6 +274,28 @@ func (d *D) FieldUTF8(name string, nBytes int) string {
})
}
// FieldUTF16BE read nBytes utf16be string and add a field
func (d *D) FieldUTF16BE(name string, nBytes int) string {
return d.FieldStrFn(name, func() (string, string) {
str, err := d.TryUTF16BE(nBytes)
if err != nil {
panic(IOError{Err: err, Name: name, Op: "FieldUTF16BE", Size: int64(nBytes) * 8, Pos: d.Pos()})
}
return str, ""
})
}
// FieldUTF16LE read nBytes utf16le string and add a field
func (d *D) FieldUTF16LE(name string, nBytes int) string {
return d.FieldStrFn(name, func() (string, string) {
str, err := d.TryUTF16LE(nBytes)
if err != nil {
panic(IOError{Err: err, Name: name, Op: "FieldUTF16LE", Size: int64(nBytes) * 8, Pos: d.Pos()})
}
return str, ""
})
}
// FieldUTF8ShortString read nBytes utf8 pascal short string and add a field
func (d *D) FieldUTF8ShortString(name string, nBytes int) string {
return d.FieldStrFn(name, func() (string, string) {

View File

@ -99,6 +99,7 @@ opus_packet Opus packet
png Portable Network Graphics file
protobuf Protobuf
protobuf_widevine Widevine protobuf
pssh_playready PlayReady PSSH
raw Raw bits
tar Tar archive
tiff Tag Image File Format