Add DASH streams for VP9 transcoding (#3275)

This commit is contained in:
DingDongSoLong4
2023-03-07 03:57:27 +02:00
committed by GitHub
parent 71e1451c94
commit 2d4384169a
21 changed files with 2118 additions and 34 deletions

13
vendor/github.com/zencoder/go-dash/v3/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright Brightcove, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,49 @@
package ptrs
func Strptr(v string) *string {
p := new(string)
*p = v
return p
}
func Intptr(v int) *int {
p := new(int)
*p = v
return p
}
func Int64ptr(v int64) *int64 {
p := new(int64)
*p = v
return p
}
func Uintptr(v uint) *uint {
p := new(uint)
*p = v
return p
}
func Uint32ptr(v uint32) *uint32 {
p := new(uint32)
*p = v
return p
}
func Uint64ptr(v uint64) *uint64 {
p := new(uint64)
*p = v
return p
}
func Boolptr(v bool) *bool {
p := new(bool)
*p = v
return p
}
func Float64ptr(v float64) *float64 {
p := new(float64)
*p = v
return p
}

206
vendor/github.com/zencoder/go-dash/v3/mpd/duration.go generated vendored Normal file
View File

@@ -0,0 +1,206 @@
// based on code from golang src/time/time.go
package mpd
import (
"encoding/xml"
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"time"
)
type Duration time.Duration
var (
rStart = "^P" // Must start with a 'P'
rDays = "(\\d+D)?" // We only allow Days for durations, not Months or Years
rTime = "(?:T" // If there's any 'time' units then they must be preceded by a 'T'
rHours = "(\\d+H)?" // Hours
rMinutes = "(\\d+M)?" // Minutes
rSeconds = "([\\d.]+S)?" // Seconds (Potentially decimal)
rEnd = ")?$" // end of regex must close "T" capture group
)
var xmlDurationRegex = regexp.MustCompile(rStart + rDays + rTime + rHours + rMinutes + rSeconds + rEnd)
func (d Duration) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
return xml.Attr{Name: name, Value: d.String()}, nil
}
func (d *Duration) UnmarshalXMLAttr(attr xml.Attr) error {
dur, err := ParseDuration(attr.Value)
if err != nil {
return err
}
*d = Duration(dur)
return nil
}
// String renders a Duration in XML Duration Data Type format
func (d *Duration) String() string {
// Largest time is 2540400h10m10.000000000s
var buf [32]byte
w := len(buf)
u := uint64(*d)
neg := *d < 0
if neg {
u = -u
}
if u < uint64(time.Second) {
// Special case: if duration is smaller than a second,
// use smaller units, like 1.2ms
var prec int
w--
buf[w] = 'S'
w--
if u == 0 {
return "PT0S"
}
/*
switch {
case u < uint64(Millisecond):
// print microseconds
prec = 3
// U+00B5 'µ' micro sign == 0xC2 0xB5
w-- // Need room for two bytes.
copy(buf[w:], "µ")
default:
// print milliseconds
prec = 6
buf[w] = 'm'
}
*/
w, u = fmtFrac(buf[:w], u, prec)
w = fmtInt(buf[:w], u)
} else {
w--
buf[w] = 'S'
w, u = fmtFrac(buf[:w], u, 9)
// u is now integer seconds
w = fmtInt(buf[:w], u%60)
u /= 60
// u is now integer minutes
if u > 0 {
w--
buf[w] = 'M'
w = fmtInt(buf[:w], u%60)
u /= 60
// u is now integer hours
// Stop at hours because days can be different lengths.
if u > 0 {
w--
buf[w] = 'H'
w = fmtInt(buf[:w], u)
}
}
}
if neg {
w--
buf[w] = '-'
}
return "PT" + string(buf[w:])
}
// fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
// tail of buf, omitting trailing zeros. it omits the decimal
// point too when the fraction is 0. It returns the index where the
// output bytes begin and the value v/10**prec.
func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
// Omit trailing zeros up to and including decimal point.
w := len(buf)
print := false
for i := 0; i < prec; i++ {
digit := v % 10
print = print || digit != 0
if print {
w--
buf[w] = byte(digit) + '0'
}
v /= 10
}
if print {
w--
buf[w] = '.'
}
return w, v
}
// fmtInt formats v into the tail of buf.
// It returns the index where the output begins.
func fmtInt(buf []byte, v uint64) int {
w := len(buf)
if v == 0 {
w--
buf[w] = '0'
} else {
for v > 0 {
w--
buf[w] = byte(v%10) + '0'
v /= 10
}
}
return w
}
func ParseDuration(str string) (time.Duration, error) {
if len(str) < 3 {
return 0, errors.New("At least one number and designator are required")
}
if strings.Contains(str, "-") {
return 0, errors.New("Duration cannot be negative")
}
// Check that only the parts we expect exist and that everything's in the correct order
if !xmlDurationRegex.Match([]byte(str)) {
return 0, errors.New("Duration must be in the format: P[nD][T[nH][nM][nS]]")
}
var parts = xmlDurationRegex.FindStringSubmatch(str)
var total time.Duration
if parts[1] != "" {
days, err := strconv.Atoi(strings.TrimRight(parts[1], "D"))
if err != nil {
return 0, fmt.Errorf("Error parsing Days: %s", err)
}
total += time.Duration(days) * time.Hour * 24
}
if parts[2] != "" {
hours, err := strconv.Atoi(strings.TrimRight(parts[2], "H"))
if err != nil {
return 0, fmt.Errorf("Error parsing Hours: %s", err)
}
total += time.Duration(hours) * time.Hour
}
if parts[3] != "" {
mins, err := strconv.Atoi(strings.TrimRight(parts[3], "M"))
if err != nil {
return 0, fmt.Errorf("Error parsing Minutes: %s", err)
}
total += time.Duration(mins) * time.Minute
}
if parts[4] != "" {
secs, err := strconv.ParseFloat(strings.TrimRight(parts[4], "S"), 64)
if err != nil {
return 0, fmt.Errorf("Error parsing Seconds: %s", err)
}
total += time.Duration(secs * float64(time.Second))
}
return total, nil
}

18
vendor/github.com/zencoder/go-dash/v3/mpd/events.go generated vendored Normal file
View File

@@ -0,0 +1,18 @@
package mpd
import "encoding/xml"
type EventStream struct {
XMLName xml.Name `xml:"EventStream"`
SchemeIDURI *string `xml:"schemeIdUri,attr"`
Value *string `xml:"value,attr,omitempty"`
Timescale *uint `xml:"timescale,attr"`
Events []Event `xml:"Event,omitempty"`
}
type Event struct {
XMLName xml.Name `xml:"Event"`
ID *string `xml:"id,attr,omitempty"`
PresentationTime *uint64 `xml:"presentationTime,attr,omitempty"`
Duration *uint64 `xml:"duration,attr,omitempty"`
}

1168
vendor/github.com/zencoder/go-dash/v3/mpd/mpd.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

57
vendor/github.com/zencoder/go-dash/v3/mpd/mpd_attr.go generated vendored Normal file
View File

@@ -0,0 +1,57 @@
package mpd
type AttrMPD interface {
GetStrptr() *string
}
type attrAvailabilityStartTime struct {
strptr *string
}
func (attr *attrAvailabilityStartTime) GetStrptr() *string {
return attr.strptr
}
// AttrAvailabilityStartTime returns AttrMPD object for NewMPD
func AttrAvailabilityStartTime(value string) AttrMPD {
return &attrAvailabilityStartTime{strptr: &value}
}
type attrMinimumUpdatePeriod struct {
strptr *string
}
func (attr *attrMinimumUpdatePeriod) GetStrptr() *string {
return attr.strptr
}
// AttrMinimumUpdatePeriod returns AttrMPD object for NewMPD
func AttrMinimumUpdatePeriod(value string) AttrMPD {
return &attrMinimumUpdatePeriod{strptr: &value}
}
type attrMediaPresentationDuration struct {
strptr *string
}
func (attr *attrMediaPresentationDuration) GetStrptr() *string {
return attr.strptr
}
// AttrMediaPresentationDuration returns AttrMPD object for NewMPD
func AttrMediaPresentationDuration(value string) AttrMPD {
return &attrMediaPresentationDuration{strptr: &value}
}
type attrPublishTime struct {
strptr *string
}
func (attr *attrPublishTime) GetStrptr() *string {
return attr.strptr
}
// AttrPublishTime returns AttrMPD object for NewMPD
func AttrPublishTime(value string) AttrMPD {
return &attrPublishTime{strptr: &value}
}

View File

@@ -0,0 +1,87 @@
package mpd
import (
"bufio"
"bytes"
"encoding/xml"
"io"
"os"
)
// Reads an MPD XML file from disk into a MPD object.
// path - File path to an MPD on disk
func ReadFromFile(path string) (*MPD, error) {
f, err := os.OpenFile(path, os.O_RDONLY, 0666)
if err != nil {
return nil, err
}
defer f.Close()
return Read(f)
}
// Reads a string into a MPD object.
// xmlStr - MPD manifest data as a string.
func ReadFromString(xmlStr string) (*MPD, error) {
b := bytes.NewBufferString(xmlStr)
return Read(b)
}
// Reads from an io.Reader interface into an MPD object.
// r - Must implement the io.Reader interface.
func Read(r io.Reader) (*MPD, error) {
var mpd MPD
d := xml.NewDecoder(r)
err := d.Decode(&mpd)
if err != nil {
return nil, err
}
return &mpd, nil
}
// Writes an MPD object to a file on disk.
// path - Output path to write the manifest to.
func (m *MPD) WriteToFile(path string) error {
// Open the file to write the XML to
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
}
defer f.Close()
if err = m.Write(f); err != nil {
return err
}
if err = f.Sync(); err != nil {
return err
}
return err
}
// Writes an MPD object to a string.
func (m *MPD) WriteToString() (string, error) {
var b bytes.Buffer
w := bufio.NewWriter(&b)
err := m.Write(w)
if err != nil {
return "", err
}
err = w.Flush()
if err != nil {
return "", err
}
return b.String(), err
}
// Writes an MPD object to an io.Writer interface
// w - Must implement the io.Writer interface.
func (m *MPD) Write(w io.Writer) error {
b, err := xml.MarshalIndent(m, "", " ")
if err != nil {
return err
}
_, _ = w.Write([]byte(xml.Header))
_, _ = w.Write(b)
_, _ = w.Write([]byte("\n"))
return nil
}

41
vendor/github.com/zencoder/go-dash/v3/mpd/pssh.go generated vendored Normal file
View File

@@ -0,0 +1,41 @@
package mpd
import (
"bytes"
"encoding/binary"
"fmt"
)
func MakePSSHBox(systemID, payload []byte) ([]byte, error) {
if len(systemID) != 16 {
return nil, fmt.Errorf("SystemID must be 16 bytes, was: %d", len(systemID))
}
psshBuf := &bytes.Buffer{}
size := uint32(12 + 16 + 4 + len(payload)) // 3 uint32s, systemID, "pssh" string and payload
if err := binary.Write(psshBuf, binary.BigEndian, size); err != nil {
return nil, err
}
if err := binary.Write(psshBuf, binary.BigEndian, []byte("pssh")); err != nil {
return nil, err
}
if err := binary.Write(psshBuf, binary.BigEndian, uint32(0)); err != nil {
return nil, err
}
if _, err := psshBuf.Write(systemID); err != nil {
return nil, err
}
if err := binary.Write(psshBuf, binary.BigEndian, uint32(len(payload))); err != nil {
return nil, err
}
if _, err := psshBuf.Write(payload); err != nil {
return nil, err
}
return psshBuf.Bytes(), nil
}

47
vendor/github.com/zencoder/go-dash/v3/mpd/segment.go generated vendored Normal file
View File

@@ -0,0 +1,47 @@
package mpd
type SegmentBase struct {
Initialization *URL `xml:"Initialization,omitempty"`
RepresentationIndex *URL `xml:"RepresentationIndex,omitempty"`
Timescale *uint32 `xml:"timescale,attr,omitempty"`
PresentationTimeOffset *uint64 `xml:"presentationTimeOffset,attr,omitempty"`
IndexRange *string `xml:"indexRange,attr,omitempty"`
IndexRangeExact *bool `xml:"indexRangeExact,attr,omitempty"`
AvailabilityTimeOffset *float32 `xml:"availabilityTimeOffset,attr,omitempty"`
AvailabilityTimeComplete *bool `xml:"availabilityTimeComplete,attr,omitempty"`
}
type MultipleSegmentBase struct {
SegmentBase
SegmentTimeline *SegmentTimeline `xml:"SegmentTimeline,omitempty"`
BitstreamSwitching *URL `xml:"BitstreamSwitching,omitempty"`
Duration *uint32 `xml:"duration,attr,omitempty"`
StartNumber *uint32 `xml:"startNumber,attr,omitempty"`
}
type SegmentList struct {
MultipleSegmentBase
SegmentURLs []*SegmentURL `xml:"SegmentURL,omitempty"`
}
type SegmentURL struct {
Media *string `xml:"media,attr,omitempty"`
MediaRange *string `xml:"mediaRange,attr,omitempty"`
Index *string `xml:"index,attr,omitempty"`
IndexRange *string `xml:"indexRange,attr,omitempty"`
}
type SegmentTimeline struct {
Segments []*SegmentTimelineSegment `xml:"S,omitempty"`
}
type SegmentTimelineSegment struct {
StartTime *uint64 `xml:"t,attr,omitempty"`
Duration uint64 `xml:"d,attr"`
RepeatCount *int `xml:"r,attr,omitempty"`
}
type URL struct {
SourceURL *string `xml:"sourceURL,attr,omitempty"`
Range *string `xml:"range,attr,omitempty"`
}

View File

@@ -0,0 +1,9 @@
package mpd
// Validate checks for incomplete MPD object
func (m *MPD) Validate() error {
if m.Profiles == nil {
return ErrNoDASHProfileSet
}
return nil
}