5.4 KiB
Executable File
5.4 KiB
Executable File
Codec Extensibility Architecture
Overview
The Gwencoder architecture is designed to be extensible for future codec support. The current implementation focuses on AV1, but the structure allows easy addition of other codecs (x264, VP9, HEVC, etc.) without major refactoring.
Architecture Pattern
Current Implementation (AV1)
encoding/
├── av1.go # AV1-specific logic
│ ├── AV1AdvancedParams struct
│ ├── DefaultAV1AdvancedParams()
│ ├── BuildSVTParams()
│ ├── BuildAV1QualityArgs()
│ └── IsAV1Codec()
Pattern for Adding New Codecs
To add a new codec (e.g., x264), follow this pattern:
-
Create codec-specific file:
encoding/x264.go -
Define parameter struct:
type X264AdvancedParams struct {
CRF int // Default: 23
Preset string // Default: "medium"
Tune string // Default: "film"
Profile string // Default: "high"
Level string // Default: "4.1"
ForceTranscode bool // Default: false
// ... other x264-specific params
}
- Implement default function:
func DefaultX264AdvancedParams() X264AdvancedParams {
return X264AdvancedParams{
CRF: 23,
Preset: "medium",
Tune: "film",
Profile: "high",
Level: "4.1",
ForceTranscode: false,
}
}
- Implement build functions:
func BuildX264Params(params X264AdvancedParams) string {
// Build x264 parameter string
}
func BuildX264QualityArgs(params X264AdvancedParams, finalCRF int) (string, string) {
// Build FFmpeg quality arguments
}
- Add codec detection:
func IsX264Codec(codec string) bool {
codec = strings.ToLower(codec)
return codec == "h264" || codec == "libx264"
}
- Integrate into main pipeline:
- Add codec detection in
encodeFile() - Dispatch to x264 encoding logic when detected
- Use same audio/stream handling infrastructure
- Add codec detection in
Integration Points
Main Encoding Function
The encodeFile() function uses codec detection to dispatch:
if useX264 {
// Use x264 encoding logic
x264Params := encoding.DefaultX264AdvancedParams()
// ... configure x264 params
// ... build x264 FFmpeg args
} else if useNVHEVC {
// Use NVENC HEVC logic (existing)
} else {
// Use AV1 encoding logic (current implementation)
av1Params := encoding.DefaultAV1AdvancedParams()
// ... configure AV1 params
// ... build AV1 FFmpeg args
}
Shared Infrastructure
All codecs share:
- Audio standardization:
encoding/audio.go(codec-agnostic) - Stream reordering:
encoding/streams.go(codec-agnostic) - Subtitle handling:
encoding/streams.go(codec-agnostic) - Resolution detection: Can be shared or codec-specific
Future Codec Support
Planned Codecs (Not Yet Implemented)
-
x264/H.264
- File:
encoding/x264.go - Parameters: CRF, preset, tune, profile, level
- Uses:
libx264encoder
- File:
-
VP9
- File:
encoding/vp9.go - Parameters: CRF, speed, tile-columns, etc.
- Uses:
libvpx-vp9encoder
- File:
-
HEVC (Software)
- File:
encoding/hevc.go - Parameters: CRF, preset, etc.
- Uses:
libx265encoder
- File:
Adding a New Codec: Step-by-Step
- Create codec file:
encoding/{codec}.go - Define parameter struct with codec-specific options
- Implement default parameters function
- Implement build functions for FFmpeg arguments
- Add codec detection helpers
- Add CLI flags for codec-specific options (optional)
- Integrate into
encodeFile()with codec detection - Test with sample files
Benefits of This Architecture
- Modularity: Each codec is self-contained
- Maintainability: Easy to update codec-specific logic
- Extensibility: New codecs don't require refactoring existing code
- Shared Infrastructure: Audio/stream handling works for all codecs
- Consistent Interface: All codecs follow the same pattern
Example: Adding x264 Support (Future)
// encoding/x264.go
package encoding
type X264AdvancedParams struct {
CRF int
Preset string
Tune string
Profile string
Level string
ForceTranscode bool
}
func DefaultX264AdvancedParams() X264AdvancedParams {
return X264AdvancedParams{
CRF: 23,
Preset: "medium",
Tune: "film",
Profile: "high",
Level: "4.1",
ForceTranscode: false,
}
}
func BuildX264Args(params X264AdvancedParams) []string {
args := []string{
"-c:v", "libx264",
"-crf", strconv.Itoa(params.CRF),
"-preset", params.Preset,
"-tune", params.Tune,
"-profile:v", params.Profile,
"-level", params.Level,
}
return args
}
Then in main.go:
if useX264 {
x264Params := encoding.DefaultX264AdvancedParams()
// Configure from mode or CLI flags
x264Args := encoding.BuildX264Args(x264Params)
args = append(args, x264Args...)
}
Notes
- Force Transcode: All codecs should support
ForceTranscodeflag - Codec Detection: Use
GetVideoCodec()to detect input codec - Skip Logic: Each codec can implement its own skip logic
- CLI Flags: Codec-specific flags should follow pattern:
--{codec}-{option}