Skip to content

Commit

Permalink
fix: PreferDF -> ForceAsNDF
Browse files Browse the repository at this point in the history
  • Loading branch information
lomavkin committed Jul 16, 2024
1 parent d8dea53 commit 5dac8d6
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 70 deletions.
94 changes: 49 additions & 45 deletions timecode/timecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ var (

// Timecode represents timecode.
type Timecode struct {
preferDF bool
sep string
lastSep string
r *rate
HH uint64
MM uint64
SS uint64
FF uint64
forceAsNDF bool
sep string
lastSep string
r *rate
HH uint64
MM uint64
SS uint64
FF uint64
}

// newNDFRate returns new NDF rate.
Expand All @@ -89,18 +89,22 @@ func newDFRate(num, den int32) (*rate, error) {
}

// newRate returns new rate.
func newRate(num, den int32, preferDF bool) (*rate, error) {
if preferDF {
r, err := newDFRate(num, den)
if err != nil {
if errors.Is(err, ErrUnsupportedFrameRate) {
return newNDFRate(num, den)
}
return nil, err
func newRate(num, den int32, forceAsNDF bool) (*rate, error) {
ndf, err := newNDFRate(num, den)
if err != nil {
return nil, err
}
if forceAsNDF {
return ndf, err
}
df, err := newDFRate(num, den)
if err != nil {
if errors.Is(err, ErrUnsupportedFrameRate) {
return ndf, nil
}
return r, nil
return nil, err
}
return newNDFRate(num, den)
return df, nil
}

// IsSupportedFrameRate returns whether frame rate is supported.
Expand All @@ -111,7 +115,7 @@ func IsSupportedFrameRate(num, den int32) bool {

// IsRepresentableFramesOptionParam represents IsRepresentableFrames option parameter.
type IsRepresentableFramesOptionParam struct {
PreferDF bool
ForceAsNDF bool
}

// IsRepresentableFramesOption represents IsRepresentableFrames option.
Expand All @@ -120,7 +124,7 @@ type IsRepresentableFramesOption func(*IsRepresentableFramesOptionParam)
// newIsRepresentableFramesOptionParam returns new IsRepresentableFramesOptionParam.
func newIsRepresentableFramesOptionParam() IsRepresentableFramesOptionParam {
return IsRepresentableFramesOptionParam{
PreferDF: true, // if frame rate is DF or NDF, assume DF
ForceAsNDF: true, // if frame rate is DF or NDF, assume NDF
}
}

Expand All @@ -136,7 +140,7 @@ func IsRepresentableFrames(frames uint64, num, den int32, opts ...IsRepresentabl
p := newIsRepresentableFramesOptionParam()
p.applyIsRepresentableFramesOption(opts...)

r, err := newRate(num, den, p.PreferDF)
r, err := newRate(num, den, p.ForceAsNDF)
if err != nil {
return false
}
Expand All @@ -145,9 +149,9 @@ func IsRepresentableFrames(frames uint64, num, den int32, opts ...IsRepresentabl

// TimecodeOptionParam represents timecode option parameter.
type TimecodeOptionParam struct {
PreferDF bool
Sep string
LastSep string
ForceAsNDF bool
Sep string
LastSep string
}

// TimecodeOption represents timecode option.
Expand All @@ -156,9 +160,9 @@ type TimecodeOption func(*TimecodeOptionParam)
// newTimecodeOptionParam returns new TimecodeOptionParam.
func newTimecodeOptionParam() TimecodeOptionParam {
return TimecodeOptionParam{
PreferDF: true, // if frame rate is 29.97 or 59.94, assume DF. otherwise, assume NDF
Sep: ":",
LastSep: ":",
ForceAsNDF: false, // true, if frame rate is DF or NDF, assume NDF. otherwise, assume DF
Sep: ":",
LastSep: ":",
}
}

Expand All @@ -174,7 +178,7 @@ func NewTimecode(frames uint64, num, den int32, opts ...TimecodeOption) (*Timeco
p := newTimecodeOptionParam()
p.applyTimecodeOption(opts...)

r, err := newRate(num, den, p.PreferDF)
r, err := newRate(num, den, p.ForceAsNDF)
if err != nil {
return nil, err
}
Expand All @@ -185,10 +189,10 @@ func NewTimecode(frames uint64, num, den int32, opts ...TimecodeOption) (*Timeco
}

tc, err := Reset(&Timecode{
preferDF: p.PreferDF,
sep: p.Sep,
lastSep: lastSep,
r: r,
forceAsNDF: p.ForceAsNDF,
sep: p.Sep,
lastSep: lastSep,
r: r,
}, frames)
if err != nil {
return nil, err
Expand All @@ -198,9 +202,9 @@ func NewTimecode(frames uint64, num, den int32, opts ...TimecodeOption) (*Timeco

// TimecodeOptionParam represents timecode option parameter.
type ParseTimecodeOptionParam struct {
PreferDF bool
Sep string
LastSep string
ForceAsNDF bool
Sep string
LastSep string
}

// ParseTimecodeOption represents parse timecode option.
Expand All @@ -209,7 +213,7 @@ type ParseTimecodeOption func(*ParseTimecodeOptionParam)
// newParseTimecodeOptionParam returns new ParseTimecodeOptionParam.
func newParseTimecodeOptionParam() ParseTimecodeOptionParam {
return ParseTimecodeOptionParam{
PreferDF: true, // if frame rate is 29.97 or 59.94, assume DF. otherwise, assume NDF
ForceAsNDF: false, // if frame rate is 29.97 or 59.94, assume NDF. otherwise, assume DF
}
}

Expand All @@ -225,7 +229,7 @@ func ParseTimecode(s string, num, den int32, opts ...ParseTimecodeOption) (*Time
p := newParseTimecodeOptionParam()
p.applyParseTimecodeOption(opts...)

r, err := newRate(num, den, p.PreferDF)
r, err := newRate(num, den, p.ForceAsNDF)
if err != nil {
return nil, err
}
Expand All @@ -252,14 +256,14 @@ func ParseTimecode(s string, num, den int32, opts ...ParseTimecodeOption) (*Time
}

return &Timecode{
preferDF: p.PreferDF,
sep: sep,
lastSep: lastSep,
r: r,
HH: uint64(hh),
MM: uint64(mm),
SS: uint64(ss),
FF: uint64(ff),
forceAsNDF: p.ForceAsNDF,
sep: sep,
lastSep: lastSep,
r: r,
HH: uint64(hh),
MM: uint64(mm),
SS: uint64(ss),
FF: uint64(ff),
}, nil
}

Expand Down
50 changes: 25 additions & 25 deletions timecode/timecode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,132 +9,132 @@ import (

func TestNewRate(t *testing.T) {
t.Run("NaN", func(t *testing.T) {
_, err := newRate(1, 0, true)
_, err := newRate(1, 0, false)
assert.Error(t, err)
})
t.Run("0fps", func(t *testing.T) {
_, err := newRate(0, 1001, true)
_, err := newRate(0, 1001, false)
assert.Error(t, err)
})
t.Run("1fps", func(t *testing.T) {
_, err := newRate(1, 1, true)
_, err := newRate(1, 1, false)
assert.Error(t, err)
})
t.Run("23.976fps", func(t *testing.T) {
r, err := newRate(24000, 1001, true)
r, err := newRate(24000, 1001, false)
assert.NoError(t, err)
assert.Equal(t, 24, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 24*60, r.framesPer1Min)
assert.Equal(t, 24*600, r.framesPer10Min)
})
t.Run("24fps", func(t *testing.T) {
r, err := newRate(24, 1, true)
r, err := newRate(24, 1, false)
assert.NoError(t, err)
assert.Equal(t, 24, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 24*60, r.framesPer1Min)
assert.Equal(t, 24*600, r.framesPer10Min)
})
t.Run("25fps", func(t *testing.T) {
r, err := newRate(25, 1, true)
r, err := newRate(25, 1, false)
assert.NoError(t, err)
assert.Equal(t, 25, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 25*60, r.framesPer1Min)
assert.Equal(t, 25*600, r.framesPer10Min)
})
t.Run("29.97fps", func(t *testing.T) {
r, err := newRate(30000, 1001, true)
r, err := newRate(30000, 1001, false)
assert.NoError(t, err)
assert.Equal(t, 30, r.roundFPS)
assert.Equal(t, 2, r.dropFrames)
assert.Equal(t, 30*60-2, r.framesPer1Min)
assert.Equal(t, 30*600-9*2, r.framesPer10Min)
})
t.Run("30fps", func(t *testing.T) {
r, err := newRate(30, 1, true)
r, err := newRate(30, 1, false)
assert.NoError(t, err)
assert.Equal(t, 30, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 30*60, r.framesPer1Min)
assert.Equal(t, 30*600, r.framesPer10Min)
})
t.Run("48fps", func(t *testing.T) {
r, err := newRate(48, 1, true)
r, err := newRate(48, 1, false)
assert.NoError(t, err)
assert.Equal(t, 48, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 48*60, r.framesPer1Min)
assert.Equal(t, 48*600, r.framesPer10Min)
})
t.Run("50fps", func(t *testing.T) {
r, err := newRate(50, 1, true)
r, err := newRate(50, 1, false)
assert.NoError(t, err)
assert.Equal(t, 50, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 50*60, r.framesPer1Min)
assert.Equal(t, 50*600, r.framesPer10Min)
})
t.Run("59.94fps", func(t *testing.T) {
r, err := newRate(60000, 1001, true)
r, err := newRate(60000, 1001, false)
assert.NoError(t, err)
assert.Equal(t, 60, r.roundFPS)
assert.Equal(t, 4, r.dropFrames)
assert.Equal(t, 60*60-4, r.framesPer1Min)
assert.Equal(t, 60*600-9*4, r.framesPer10Min)
})
t.Run("60fps", func(t *testing.T) {
r, err := newRate(60, 1, true)
r, err := newRate(60, 1, false)
assert.NoError(t, err)
assert.Equal(t, 60, r.roundFPS)
assert.Equal(t, 0, r.dropFrames)
assert.Equal(t, 60*60, r.framesPer1Min)
assert.Equal(t, 60*600, r.framesPer10Min)
})
t.Run("error/23.995fps", func(t *testing.T) {
r, err := newRate(29995, 1000, true)
r, err := newRate(29995, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/23.997fps", func(t *testing.T) {
r, err := newRate(29997, 1000, true)
r, err := newRate(29997, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/29.96fps", func(t *testing.T) {
r, err := newRate(29960, 1000, true)
r, err := newRate(29960, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/29.98fps", func(t *testing.T) {
r, err := newRate(29980, 1000, true)
r, err := newRate(29980, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/59.93fps", func(t *testing.T) {
r, err := newRate(59930, 1000, true)
r, err := newRate(59930, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/59.95fps", func(t *testing.T) {
r, err := newRate(59950, 1000, true)
r, err := newRate(59950, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
t.Run("error/60.001fps", func(t *testing.T) {
r, err := newRate(60001, 1000, true)
r, err := newRate(60001, 1000, false)
assert.Equal(t, ErrUnsupportedFrameRate, err)
assert.Nil(t, r)
})
}

func TestNewTimecodeNDF(t *testing.T) {
assumeDF := func(p *TimecodeOptionParam) {
p.PreferDF = true
p.ForceAsNDF = false
}
assumeNDF := func(p *TimecodeOptionParam) {
p.PreferDF = false
p.ForceAsNDF = true
}

t.Run("NaN", func(t *testing.T) {
Expand Down Expand Up @@ -529,7 +529,7 @@ func TestNewTimecodeNDF(t *testing.T) {

func TestNewTimecodeDF(t *testing.T) {
assumeDF := func(p *TimecodeOptionParam) {
p.PreferDF = true
p.ForceAsNDF = false
}

t.Run("30DF", func(t *testing.T) {
Expand Down Expand Up @@ -637,7 +637,7 @@ func TestParseTimecode(t *testing.T) {
})
t.Run("ParseTimecode/29.97NDF", func(t *testing.T) {
tc, err := ParseTimecode("00:01:00;00", 30000, 1001, func(p *ParseTimecodeOptionParam) {
p.PreferDF = false
p.ForceAsNDF = true
}) // NDF
assert.NoError(t, err)
assert.Equal(t, "00:01:00:00", tc.String())
Expand Down Expand Up @@ -742,7 +742,7 @@ func TestAdd(t *testing.T) {
t.Run("Add/mismatch frame rate2", func(t *testing.T) {
tc1, _ := NewTimecode(1, 30000, 1001)
tc2, _ := NewTimecode(1, 30000, 1001, func(p *TimecodeOptionParam) {
p.PreferDF = false
p.ForceAsNDF = true
})
tc3, err := tc1.Add(tc2)
assert.Nil(t, tc3)
Expand Down Expand Up @@ -824,7 +824,7 @@ func TestTimecodeOption(t *testing.T) {
}
opt2 := func(p *TimecodeOptionParam) {
p.LastSep = ";"
p.PreferDF = false
p.ForceAsNDF = true
}
tc, err := NewTimecode(3596, 60000, 1001, opt1, opt2)
assert.NoError(t, err)
Expand Down

0 comments on commit 5dac8d6

Please sign in to comment.