Compare commits

..

No commits in common. "c6755cb58586e6294224df2f9a23df1d0379e086" and "8ba0319c6e5e38efdfbd313a45bf629642d3824c" have entirely different histories.

4 changed files with 48 additions and 61 deletions

View file

@ -2,6 +2,6 @@
name = "cz_conventional_commits" name = "cz_conventional_commits"
tag_format = "$version" tag_format = "$version"
version_scheme = "semver2" version_scheme = "semver2"
version = "0.3.0" version = "0.2.0"
update_changelog_on_bump = true update_changelog_on_bump = true
major_version_zero = true major_version_zero = true

1
.gitignore vendored
View file

@ -1,3 +1,2 @@
fps-go-brr fps-go-brr
fps-go-brr-compact fps-go-brr-compact
.vscode/settings.json

View file

@ -1,12 +1,3 @@
## 0.3.0 (2025-06-15)
### Refactor
- change variable and function names to fit with golang conventions
- remove pointless else statments
- add package string
- **gitignore**: ignore compact build binary
## 0.2.0 (2025-06-14) ## 0.2.0 (2025-06-14)
### Feat ### Feat

83
main.go
View file

@ -1,4 +1,3 @@
// A Go CLI tool for video frame analysis and comparison. Analyze frame persistence, detect dropped frames, and export data for visualization tools like those used by Digital Foundry.
package main package main
import ( import (
@ -23,7 +22,7 @@ func main() {
Usage: "Count frames", Usage: "Count frames",
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx context.Context, cmd *cli.Command) error {
return countVideoFrames(cmd.Args().First()) return count_video_frames(cmd.Args().First())
}, },
}, },
{ {
@ -40,12 +39,12 @@ func main() {
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx context.Context, cmd *cli.Command) error {
firstFrame, _ := getImageFromFilePath(cmd.StringArg("frame1")) first_frame, _ := getImageFromFilePath(cmd.StringArg("frame1"))
secondFrame, _ := getImageFromFilePath(cmd.StringArg("frame2")) second_frame, _ := getImageFromFilePath(cmd.StringArg("frame2"))
firstRGBA := imageToRGBA(firstFrame) first_rgba := imageToRGBA(first_frame)
secondRGBA := imageToRGBA(secondFrame) second_rgba := imageToRGBA(second_frame)
return compareFrames(firstRGBA, secondRGBA) return compare_frames(first_rgba, second_rgba)
}, },
}, },
{ {
@ -62,12 +61,12 @@ func main() {
Action: func(ctx context.Context, cmd *cli.Command) error { Action: func(ctx context.Context, cmd *cli.Command) error {
firstFrame, _ := getImageFromFilePath(cmd.StringArg("frame1")) first_frame, _ := getImageFromFilePath(cmd.StringArg("frame1"))
secondFrame, _ := getImageFromFilePath(cmd.StringArg("frame2")) second_frame, _ := getImageFromFilePath(cmd.StringArg("frame2"))
firstRGBA := imageToRGBA(firstFrame) first_rgba := imageToRGBA(first_frame)
secondRGBA := imageToRGBA(secondFrame) second_rgba := imageToRGBA(second_frame)
return compareFramesAlt(firstRGBA, secondRGBA) return compare_frames_alt(first_rgba, second_rgba)
}, },
}, },
{ {
@ -120,7 +119,7 @@ func main() {
} }
} }
// countVideoFrames // count_video_frames
// Prints out the total ammount of frames within `video` // Prints out the total ammount of frames within `video`
// //
// Parameters: // Parameters:
@ -128,18 +127,18 @@ func main() {
// //
// Returns: // Returns:
// - error // - error
func countVideoFrames(video string) error { func count_video_frames(video string) error {
log.Default().Print("Trying to open video at: " + video) log.Default().Print("Trying to open video at: " + video)
videoFile, _ := vidio.NewVideo(video) video_file, _ := vidio.NewVideo(video)
count := 0 count := 0
for videoFile.Read() { for video_file.Read() {
count++ count++
} }
log.Default().Println("Video total frames: " + strconv.Itoa(count)) log.Default().Println("Video total frames: " + strconv.Itoa(count))
return nil return nil
} }
func compareFrames(frame1 *image.RGBA, frame2 *image.RGBA) error { func compare_frames(frame1 *image.RGBA, frame2 *image.RGBA) error {
accumError := int64(0) accumError := int64(0)
for i := 0; i < len(frame1.Pix); i++ { for i := 0; i < len(frame1.Pix); i++ {
@ -151,7 +150,7 @@ func compareFrames(frame1 *image.RGBA, frame2 *image.RGBA) error {
return nil return nil
} }
func compareFramesAlt(frame1 *image.RGBA, frame2 *image.RGBA) error { func compare_frames_alt(frame1 *image.RGBA, frame2 *image.RGBA) error {
// diff_frame := image.NewRGBA(frame1.Rect) // diff_frame := image.NewRGBA(frame1.Rect)
accumError := int64(0) accumError := int64(0)
for i := 0; i < len(frame1.Pix); i++ { for i := 0; i < len(frame1.Pix); i++ {
@ -173,10 +172,9 @@ func isDiffUInt8(x, y uint8) bool {
sq := d * d sq := d * d
if sq > 0 { if sq > 0 {
return true return true
} } else {
return false return false
}
} }
func isDiffUInt8WithTolerance(x, y uint8, tolerance uint64) bool { func isDiffUInt8WithTolerance(x, y uint8, tolerance uint64) bool {
@ -184,46 +182,45 @@ func isDiffUInt8WithTolerance(x, y uint8, tolerance uint64) bool {
sq := d * d sq := d * d
if sq > tolerance { if sq > tolerance {
return true return true
} } else {
return false return false
}
} }
func countUniqueVideoFrames(videoPath1 string, videoPath2 string, minDiff uint64, useSqDiff bool) error { func countUniqueVideoFrames(video_path1 string, video_path2 string, min_diff uint64, use_sq_diff bool) error {
video1, _ := vidio.NewVideo(videoPath1) video1, _ := vidio.NewVideo(video_path1)
video2, _ := vidio.NewVideo(videoPath2) video2, _ := vidio.NewVideo(video_path2)
video1Frame := image.NewRGBA(image.Rect(0, 0, video1.Width(), video1.Height())) video1_frame := image.NewRGBA(image.Rect(0, 0, video1.Width(), video1.Height()))
video2Frame := image.NewRGBA(image.Rect(0, 0, video2.Width(), video2.Height())) video2_frame := image.NewRGBA(image.Rect(0, 0, video2.Width(), video2.Height()))
video1.SetFrameBuffer(video1Frame.Pix) video1.SetFrameBuffer(video1_frame.Pix)
video2.SetFrameBuffer(video2Frame.Pix) video2.SetFrameBuffer(video2_frame.Pix)
totalFrames := 0 total_frames := 0
uniqueFrames := 0 unique_frames := 0
for video1.Read() { for video1.Read() {
totalFrames++ total_frames++
video2.Read() video2.Read()
accumError := uint64(0) accumError := uint64(0)
for i := 0; i < len(video1Frame.Pix); i++ { for i := 0; i < len(video1_frame.Pix); i++ {
if useSqDiff { if use_sq_diff {
if isDiffUInt8WithTolerance(video1Frame.Pix[i], video2Frame.Pix[i], minDiff) { if isDiffUInt8WithTolerance(video1_frame.Pix[i], video2_frame.Pix[i], min_diff) {
accumError++ accumError++
} }
} else { } else {
if isDiffUInt8(video1Frame.Pix[i], video2Frame.Pix[i]) { if isDiffUInt8(video1_frame.Pix[i], video2_frame.Pix[i]) {
accumError++ accumError++
} }
} }
} }
if minDiff <= accumError { if min_diff <= accumError {
uniqueFrames++ unique_frames++
log.Default().Println("[" + strconv.Itoa(totalFrames) + "]Unique frame") log.Default().Println("[" + strconv.Itoa(total_frames) + "]Unique frame")
} else { } else {
log.Default().Println("[" + strconv.Itoa(totalFrames) + "]Non-unique frame") log.Default().Println("[" + strconv.Itoa(total_frames) + "]Non-unique frame")
} }
} }
video1.Close() video1.Close()
video2.Close() video2.Close()
log.Default().Println(strconv.Itoa(uniqueFrames) + "/" + strconv.Itoa(totalFrames) + " are unique!") log.Default().Println(strconv.Itoa(unique_frames) + "/" + strconv.Itoa(total_frames) + " are unique!")
return nil return nil
} }