Skip to content

Commit 49ec79e

Browse files
committed
refactor(processor): extract filter graph setup into shared helper
Consolidate duplicated filter graph boilerplate from createAnalysisFilterGraph and CreateProcessingFilterGraph into a single setupFilterGraph helper function. - Add setupFilterGraph() handling common boilerplate: - Graph allocation - abuffer/abuffersink filter lookup - Channel layout description - Buffer source creation with decoder context - Buffer sink creation - Filter specification parsing with inputs/outputs - Graph configuration - Simplify createAnalysisFilterGraph to build filter spec and delegate - Reduce CreateProcessingFilterGraph to single delegation call - Net reduction of 83 lines (-7% across both files)
1 parent ecedd87 commit 49ec79e

2 files changed

Lines changed: 15 additions & 97 deletions

File tree

internal/processor/analyzer.go

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -345,69 +345,6 @@ func createAnalysisFilterGraph(
345345
decCtx *ffmpeg.AVCodecContext,
346346
targetI, targetTP, targetLRA float64,
347347
) (*ffmpeg.AVFilterGraph, *ffmpeg.AVFilterContext, *ffmpeg.AVFilterContext, error) {
348-
349-
filterGraph := ffmpeg.AVFilterGraphAlloc()
350-
if filterGraph == nil {
351-
return nil, nil, nil, fmt.Errorf("failed to allocate filter graph")
352-
}
353-
354-
// Get abuffer and abuffersink filters
355-
bufferSrc := ffmpeg.AVFilterGetByName(ffmpeg.GlobalCStr("abuffer"))
356-
bufferSink := ffmpeg.AVFilterGetByName(ffmpeg.GlobalCStr("abuffersink"))
357-
if bufferSrc == nil || bufferSink == nil {
358-
ffmpeg.AVFilterGraphFree(&filterGraph)
359-
return nil, nil, nil, fmt.Errorf("abuffer or abuffersink filter not found")
360-
}
361-
362-
// Get channel layout description
363-
layoutPtr := ffmpeg.AllocCStr(64)
364-
defer layoutPtr.Free()
365-
366-
if _, err := ffmpeg.AVChannelLayoutDescribe(decCtx.ChLayout(), layoutPtr, 64); err != nil {
367-
ffmpeg.AVFilterGraphFree(&filterGraph)
368-
return nil, nil, nil, fmt.Errorf("failed to get channel layout: %w", err)
369-
}
370-
371-
// Create abuffer source
372-
pktTimebase := decCtx.PktTimebase()
373-
args := fmt.Sprintf(
374-
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s",
375-
pktTimebase.Num(), pktTimebase.Den(),
376-
decCtx.SampleRate(),
377-
ffmpeg.AVGetSampleFmtName(decCtx.SampleFmt()).String(),
378-
layoutPtr.String(),
379-
)
380-
381-
argsC := ffmpeg.ToCStr(args)
382-
defer argsC.Free()
383-
384-
var bufferSrcCtx *ffmpeg.AVFilterContext
385-
if _, err := ffmpeg.AVFilterGraphCreateFilter(
386-
&bufferSrcCtx,
387-
bufferSrc,
388-
ffmpeg.GlobalCStr("in"),
389-
argsC,
390-
nil,
391-
filterGraph,
392-
); err != nil {
393-
ffmpeg.AVFilterGraphFree(&filterGraph)
394-
return nil, nil, nil, fmt.Errorf("failed to create abuffer: %w", err)
395-
}
396-
397-
// Create abuffersink
398-
var bufferSinkCtx *ffmpeg.AVFilterContext
399-
if _, err := ffmpeg.AVFilterGraphCreateFilter(
400-
&bufferSinkCtx,
401-
bufferSink,
402-
ffmpeg.GlobalCStr("out"),
403-
nil,
404-
nil,
405-
filterGraph,
406-
); err != nil {
407-
ffmpeg.AVFilterGraphFree(&filterGraph)
408-
return nil, nil, nil, fmt.Errorf("failed to create abuffersink: %w", err)
409-
}
410-
411348
// Build filter string for analysis pass
412349
// astats provides noise floor and dynamic range measurements for adaptive gate and compression
413350
// aspectralstats measures spectral centroid and rolloff for adaptive de-esser targeting
@@ -417,35 +354,5 @@ func createAnalysisFilterGraph(
417354
filterSpec := fmt.Sprintf("astats=metadata=1:measure_overall=Noise_floor+Dynamic_range+RMS_level+Peak_level,aspectralstats=win_size=2048:win_func=hann:measure=centroid+rolloff,ebur128=metadata=1:target=%.0f",
418355
targetI)
419356

420-
// Parse filter graph
421-
outputs := ffmpeg.AVFilterInoutAlloc()
422-
inputs := ffmpeg.AVFilterInoutAlloc()
423-
defer ffmpeg.AVFilterInoutFree(&outputs)
424-
defer ffmpeg.AVFilterInoutFree(&inputs)
425-
426-
outputs.SetName(ffmpeg.ToCStr("in"))
427-
outputs.SetFilterCtx(bufferSrcCtx)
428-
outputs.SetPadIdx(0)
429-
outputs.SetNext(nil)
430-
431-
inputs.SetName(ffmpeg.ToCStr("out"))
432-
inputs.SetFilterCtx(bufferSinkCtx)
433-
inputs.SetPadIdx(0)
434-
inputs.SetNext(nil)
435-
436-
filterSpecC := ffmpeg.ToCStr(filterSpec)
437-
defer filterSpecC.Free()
438-
439-
if _, err := ffmpeg.AVFilterGraphParsePtr(filterGraph, filterSpecC, &inputs, &outputs, nil); err != nil {
440-
ffmpeg.AVFilterGraphFree(&filterGraph)
441-
return nil, nil, nil, fmt.Errorf("failed to parse filter graph: %w", err)
442-
}
443-
444-
// Configure filter graph
445-
if _, err := ffmpeg.AVFilterGraphConfig(filterGraph, nil); err != nil {
446-
ffmpeg.AVFilterGraphFree(&filterGraph)
447-
return nil, nil, nil, fmt.Errorf("failed to configure filter graph: %w", err)
448-
}
449-
450-
return filterGraph, bufferSrcCtx, bufferSinkCtx, nil
357+
return setupFilterGraph(decCtx, filterSpec)
451358
}

internal/processor/filters.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,21 @@ func CreateProcessingFilterGraph(
589589
decCtx *ffmpeg.AVCodecContext,
590590
config *FilterChainConfig,
591591
) (*ffmpeg.AVFilterGraph, *ffmpeg.AVFilterContext, *ffmpeg.AVFilterContext, error) {
592+
return setupFilterGraph(decCtx, config.BuildFilterSpec())
593+
}
592594

595+
// setupFilterGraph creates and configures an FFmpeg filter graph with the given
596+
// filter specification. It handles all common boilerplate: graph allocation,
597+
// buffer source/sink creation, parsing, and configuration.
598+
//
599+
// Returns the configured filter graph and source/sink contexts, or an error.
600+
// The caller is responsible for freeing the filter graph with AVFilterGraphFree.
601+
func setupFilterGraph(decCtx *ffmpeg.AVCodecContext, filterSpec string) (
602+
*ffmpeg.AVFilterGraph,
603+
*ffmpeg.AVFilterContext,
604+
*ffmpeg.AVFilterContext,
605+
error,
606+
) {
593607
filterGraph := ffmpeg.AVFilterGraphAlloc()
594608
if filterGraph == nil {
595609
return nil, nil, nil, fmt.Errorf("failed to allocate filter graph")
@@ -652,9 +666,6 @@ func CreateProcessingFilterGraph(
652666
return nil, nil, nil, fmt.Errorf("failed to create abuffersink: %w", err)
653667
}
654668

655-
// Build the complete filter specification
656-
filterSpec := config.BuildFilterSpec()
657-
658669
// Parse filter graph
659670
outputs := ffmpeg.AVFilterInoutAlloc()
660671
inputs := ffmpeg.AVFilterInoutAlloc()

0 commit comments

Comments
 (0)