added vfr detection, to improve preview generation performance (#3376)

This commit is contained in:
JoeSmithStarkers 2023-02-17 13:59:36 +11:00 committed by GitHub
parent f92ba7ba53
commit 390f72207c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 12 deletions

View File

@ -44,7 +44,7 @@ func (t *GeneratePreviewTask) Start(ctx context.Context) {
return
}
if err := t.generateVideo(videoChecksum, videoFile.VideoStreamDuration); err != nil {
if err := t.generateVideo(videoChecksum, videoFile.VideoStreamDuration, videoFile.FrameRate); err != nil {
logger.Errorf("error generating preview: %v", err)
logErrorOutput(err)
return
@ -59,12 +59,18 @@ func (t *GeneratePreviewTask) Start(ctx context.Context) {
}
}
func (t GeneratePreviewTask) generateVideo(videoChecksum string, videoDuration float64) error {
func (t GeneratePreviewTask) generateVideo(videoChecksum string, videoDuration float64, videoFrameRate float64) error {
videoFilename := t.Scene.Path
useVsync2 := false
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, false); err != nil {
if videoFrameRate <= 0.01 {
logger.Errorf("[generator] Video framerate very low/high (%f) most likely vfr so using -vsync 2", videoFrameRate)
useVsync2 = true
}
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, false, useVsync2); err != nil {
logger.Warnf("[generator] failed generating scene preview, trying fallback")
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, true); err != nil {
if err := t.generator.PreviewVideo(context.TODO(), videoFilename, videoDuration, videoChecksum, t.Options, true, useVsync2); err != nil {
return err
}
}

View File

@ -68,7 +68,7 @@ func (g PreviewOptions) getStepSizeAndOffset(videoDuration float64) (stepSize fl
return
}
func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration float64, hash string, options PreviewOptions, fallback bool) error {
func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration float64, hash string, options PreviewOptions, fallback bool, useVsync2 bool) error {
lockCtx := g.LockManager.ReadLock(ctx, input)
defer lockCtx.Cancel()
@ -81,7 +81,7 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration
logger.Infof("[generator] generating video preview for %s", input)
if err := g.generateFile(lockCtx, g.ScenePaths, mp4Pattern, output, g.previewVideo(input, videoDuration, options, fallback)); err != nil {
if err := g.generateFile(lockCtx, g.ScenePaths, mp4Pattern, output, g.previewVideo(input, videoDuration, options, fallback, useVsync2)); err != nil {
return err
}
@ -90,10 +90,10 @@ func (g Generator) PreviewVideo(ctx context.Context, input string, videoDuration
return nil
}
func (g *Generator) previewVideo(input string, videoDuration float64, options PreviewOptions, fallback bool) generateFn {
func (g *Generator) previewVideo(input string, videoDuration float64, options PreviewOptions, fallback bool, useVsync2 bool) generateFn {
// #2496 - generate a single preview video for videos shorter than segments * segment duration
if videoDuration < options.SegmentDuration*float64(options.Segments) {
return g.previewVideoSingle(input, videoDuration, options, fallback)
return g.previewVideoSingle(input, videoDuration, options, fallback, useVsync2)
}
return func(lockCtx *fsutil.LockContext, tmpFn string) error {
@ -131,7 +131,7 @@ func (g *Generator) previewVideo(input string, videoDuration float64, options Pr
Preset: options.Preset,
}
if err := g.previewVideoChunk(lockCtx, input, chunkOptions, fallback); err != nil {
if err := g.previewVideoChunk(lockCtx, input, chunkOptions, fallback, useVsync2); err != nil {
return err
}
}
@ -150,7 +150,7 @@ func (g *Generator) previewVideo(input string, videoDuration float64, options Pr
}
}
func (g *Generator) previewVideoSingle(input string, videoDuration float64, options PreviewOptions, fallback bool) generateFn {
func (g *Generator) previewVideoSingle(input string, videoDuration float64, options PreviewOptions, fallback bool, useVsync2 bool) generateFn {
return func(lockCtx *fsutil.LockContext, tmpFn string) error {
chunkOptions := previewChunkOptions{
StartTime: 0,
@ -160,7 +160,7 @@ func (g *Generator) previewVideoSingle(input string, videoDuration float64, opti
Preset: options.Preset,
}
return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback)
return g.previewVideoChunk(lockCtx, input, chunkOptions, fallback, useVsync2)
}
}
@ -172,7 +172,7 @@ type previewChunkOptions struct {
Preset string
}
func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, options previewChunkOptions, fallback bool) error {
func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, options previewChunkOptions, fallback bool, useVsync2 bool) error {
var videoFilter ffmpeg.VideoFilter
videoFilter = videoFilter.ScaleWidth(scenePreviewWidth)
@ -189,6 +189,10 @@ func (g Generator) previewVideoChunk(lockCtx *fsutil.LockContext, fn string, opt
"-strict", "-2",
)
if useVsync2 {
videoArgs = append(videoArgs, "-vsync", "2")
}
trimOptions := transcoder.TranscodeOptions{
OutputPath: options.OutputPath,
StartTime: options.StartTime,