# kearcer/ffmpeg_application architecture

> Architecture diagram of the GitHub repository kearcer/ffmpeg_application, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/kearcer/ffmpeg_application
- Repository: https://github.com/kearcer/ffmpeg_application

## Overview

1. This repo is a small FFmpeg learning workspace with two separate execution paths: a minimal command-line transcode wrapper in `src/main.cpp`, and a more explicit FFmpeg API pipeline demo in `src/pipeline_demo.cpp`. The first path shells out to `third_party/ffmpeg/bin/ffmpeg.exe`; the second links directly against FFmpeg libraries.

2. The build boundary is handled by `CMakeLists.txt`, with a Windows/Visual Studio-oriented setup. The repo vendors the FFmpeg toolchain under `third_party/ffmpeg/`, including headers, import libraries, and runtime executables, so the project does not depend on a system-installed FFmpeg.

3. The simplest runtime flow is the “external process” transcode example. `main.cpp` builds an ffmpeg command equivalent to `ffmpeg.exe -y -i input.mp4 -c:v mpeg4 -q:v 5 -c:a aac -b:a 128k output.mp4`, then executes it. This path is meant to demonstrate basic transcoding without exposing FFmpeg’s C APIs.

4. The deeper architecture is the API-based video transcode pipeline. Its entry point is `src/pipeline_demo.cpp`, which orchestrates a five-stage media processing chain implemented in `include/pipeline/` and `src/pipeline/`.

5. The pipeline is intentionally split into distinct subsystems that map to FFmpeg concepts:
   - `Demuxer` handles container reading and stream extraction.
   - `Decoder` converts compressed packets into raw frames.
   - `FramePreprocessor` adjusts raw video frames into a form suitable for encoding, typically pixel-format or frame-shape preparation.
   - `Encoder` converts prepared frames back into compressed packets.
   - `Muxer` writes encoded packets into the output container.

6. The data flow in the pipeline is linear and video-centric: input file → demuxed `AVPacket` → decoded `AVFrame` → preprocessed `AVFrame` → encoded `AVPacket` → output file. The README notes that non-video streams may be present, but this demo explicitly skips them to keep the learning path focused.

7. `pipeline_logger.h/.cpp` provides observability for the pipeline stages. The log labels like `[DEMUX IN]`, `[DECODE OUT]`, `[ENCODE IN]`, and `[MUX OUT]` make the internal state transitions visible, which is important because the repo is structured as a teaching aid rather than a production abstraction layer.

8. `ffmpeg_helpers.h/.cpp` acts as a shared utility boundary around FFmpeg boilerplate and error handling. This kind of helper layer typically centralizes repetitive API calls, format/rational conversions, and status reporting so the stage classes stay focused on their own responsibilities.

9. `video_transcode_pipeline.h/.cpp` is the top-level coordinator for the API demo. It composes the five stage objects into one orchestrated workflow, so the repo has a clear separation between “pipeline assembly” and “stage implementation.”

10. The `media/` directory contains sample inputs and generated outputs. It serves as a local test fixture boundary: one known input video and several output artifacts that show expected results from the starter command-line path and the pipeline demo.

11. From an architecture-diagram perspective, the important external dependency is FFmpeg itself, but there are two forms of integration:
    - process-level invocation of `ffmpeg.exe` for the simplest demo
    - library-level linkage to `libavformat`, `libavcodec`, `libavutil`, `libswscale`, and `libswresample` for the pipeline demo

12. Overall, this repository is not a general multimedia app; it is a deliberately small learning scaffold. Its main architectural idea is to expose the FFmpeg transcode lifecycle in two layers: a black-box executable call for quick success, and a decomposed C++ pipeline for understanding the media-processing boundaries.

Main entry points: [`src/pipeline/video_transcode_pipeline.cpp`](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/video_transcode_pipeline.cpp) (Transcode Pipeline), [`CMakeLists.txt`](https://github.com/kearcer/ffmpeg_application/blob/main/CMakeLists.txt) (CMake), [`src/pipeline/ffmpeg_helpers.cpp`](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/ffmpeg_helpers.cpp) (FFmpeg Helpers), [`src/main.cpp`](https://github.com/kearcer/ffmpeg_application/blob/main/src/main.cpp) (CLI Transcode)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_g_app["Application"]
  node_n_cmake["CMake<br/>build system<br/>[CMakeLists.txt]"]
  node_n_main["CLI Transcode<br/>exe wrapper<br/>[main.cpp]"]
  node_n_demo["Pipeline Demo<br/>demo entry<br/>[pipeline_demo.cpp]"]
end

subgraph group_g_pipeline["API Pipeline"]
  node_n_pipeline["Transcode Pipeline<br/>orchestrator"]
  node_n_demuxer["Demuxer<br/>container reader<br/>[demuxer.cpp]"]
  node_n_decoder["Decoder<br/>packet-to-frame<br/>[decoder.cpp]"]
  node_n_preproc["Frame Prep<br/>frame transform"]
  node_n_encoder["Encoder<br/>frame-to-packet<br/>[encoder.cpp]"]
  node_n_muxer["Muxer<br/>container writer<br/>[muxer.cpp]"]
  node_n_helpers["FFmpeg Helpers<br/>utility layer<br/>[ffmpeg_helpers.cpp]"]
  node_n_logger["Pipeline Logger<br/>observability"]
end

subgraph group_g_ffmpeg["Vendored FFmpeg"]
  node_n_ffmpeg_bin["ffmpeg.exe<br/>external tool<br/>[ffmpeg.exe]"]
  node_n_ffmpeg_inc["FFmpeg Headers<br/>sdk headers"]
  node_n_ffmpeg_libs[("FFmpeg Libs<br/>import libs")]
end

subgraph group_g_media["Media Fixtures"]
  node_n_input["Input Video<br/>fixture<br/>[input.mp4]"]
  node_n_out1["CLI Output<br/>artifact"]
  node_n_out2["Pipeline Output<br/>artifact"]
  node_n_out3["Alt Outputs<br/>artifact"]
end

node_n_cmake -->|"builds"| node_n_main
node_n_cmake -->|"builds"| node_n_demo
node_n_cmake -->|"links"| node_n_pipeline
node_n_cmake -->|"uses headers"| node_n_ffmpeg_inc
node_n_cmake -->|"links libs"| node_n_ffmpeg_libs
node_n_main -->|"executes"| node_n_ffmpeg_bin
node_n_main -->|"reads"| node_n_input
node_n_main -->|"writes"| node_n_out1
node_n_demo -->|"orchestrates"| node_n_pipeline
node_n_pipeline -->|"assembles"| node_n_demuxer
node_n_pipeline -->|"assembles"| node_n_decoder
node_n_pipeline -->|"assembles"| node_n_preproc
node_n_pipeline -->|"assembles"| node_n_encoder
node_n_pipeline -->|"assembles"| node_n_muxer
node_n_demuxer -->|"uses"| node_n_helpers
node_n_decoder -->|"uses"| node_n_helpers
node_n_preproc -->|"uses"| node_n_helpers
node_n_encoder -->|"uses"| node_n_helpers
node_n_muxer -->|"uses"| node_n_helpers
node_n_pipeline -->|"logs"| node_n_logger
node_n_demuxer -->|"reads"| node_n_input
node_n_muxer -->|"writes"| node_n_out2
node_n_muxer -->|"writes"| node_n_out3
node_n_pipeline -->|"includes"| node_n_ffmpeg_inc
node_n_pipeline -->|"links"| node_n_ffmpeg_libs

click node_n_cmake "https://github.com/kearcer/ffmpeg_application/blob/main/CMakeLists.txt"
click node_n_main "https://github.com/kearcer/ffmpeg_application/blob/main/src/main.cpp"
click node_n_demo "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline_demo.cpp"
click node_n_pipeline "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/video_transcode_pipeline.cpp"
click node_n_demuxer "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/demuxer.cpp"
click node_n_decoder "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/decoder.cpp"
click node_n_preproc "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/frame_preprocessor.cpp"
click node_n_encoder "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/encoder.cpp"
click node_n_muxer "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/muxer.cpp"
click node_n_helpers "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/ffmpeg_helpers.cpp"
click node_n_logger "https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/pipeline_logger.cpp"
click node_n_ffmpeg_bin "https://github.com/kearcer/ffmpeg_application/blob/main/third_party/ffmpeg/bin/ffmpeg.exe"
click node_n_ffmpeg_inc "https://github.com/kearcer/ffmpeg_application/tree/main/third_party/ffmpeg/include"
click node_n_ffmpeg_libs "https://github.com/kearcer/ffmpeg_application/tree/main/third_party/ffmpeg/lib"
click node_n_input "https://github.com/kearcer/ffmpeg_application/blob/main/media/input.mp4"
click node_n_out1 "https://github.com/kearcer/ffmpeg_application/blob/main/media/output_moved_layout.mp4"
click node_n_out2 "https://github.com/kearcer/ffmpeg_application/blob/main/media/pipeline_output.mp4"
click node_n_out3 "https://github.com/kearcer/ffmpeg_application/blob/main/media/pipeline_output_cpp_style.mp4"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_n_cmake,node_n_main,node_n_demo toneBlue
class node_n_pipeline,node_n_demuxer,node_n_decoder,node_n_preproc,node_n_encoder,node_n_muxer,node_n_helpers,node_n_logger toneAmber
class node_n_ffmpeg_bin,node_n_ffmpeg_inc,node_n_ffmpeg_libs toneMint
class node_n_input,node_n_out1,node_n_out2,node_n_out3 toneRose
```

## Components

### Application

Repo-owned build targets and C++ demo flows.

- [CMake](https://github.com/kearcer/ffmpeg_application/blob/main/CMakeLists.txt): build system · Configures the Windows-oriented build and links vendored FFmpeg. · `CMakeLists.txt`
- [CLI Transcode](https://github.com/kearcer/ffmpeg_application/blob/main/src/main.cpp): exe wrapper · Builds and runs an ffmpeg.exe command for a minimal transcode demo. · `src/main.cpp`
- [Pipeline Demo](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline_demo.cpp): demo entry · Entry point for the explicit FFmpeg API pipeline example. · `src/pipeline_demo.cpp`

### API Pipeline

Decomposed FFmpeg-based transcode workflow.

- [Transcode Pipeline](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/video_transcode_pipeline.cpp): orchestrator · Coordinates the stage objects into one linear media-processing flow. · `src/pipeline/video_transcode_pipeline.cpp`
- [Demuxer](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/demuxer.cpp): container reader · Reads containers and extracts packets from input streams. · `src/pipeline/demuxer.cpp`
- [Decoder](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/decoder.cpp): packet-to-frame · Converts compressed packets into raw frames. · `src/pipeline/decoder.cpp`
- [Frame Prep](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/frame_preprocessor.cpp): frame transform · Normalizes video frames for encoder input. · `src/pipeline/frame_preprocessor.cpp`
- [Encoder](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/encoder.cpp): frame-to-packet · Compresses prepared frames into output packets. · `src/pipeline/encoder.cpp`
- [Muxer](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/muxer.cpp): container writer · Writes encoded packets into the destination container. · `src/pipeline/muxer.cpp`
- [FFmpeg Helpers](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/ffmpeg_helpers.cpp): utility layer · Shared boilerplate for API setup, conversions, and error handling. · `src/pipeline/ffmpeg_helpers.cpp`
- [Pipeline Logger](https://github.com/kearcer/ffmpeg_application/blob/main/src/pipeline/pipeline_logger.cpp): observability · Emits stage markers such as demux, decode, encode, and mux transitions. · `src/pipeline/pipeline_logger.cpp`

### Vendored FFmpeg

Bundled binaries, headers, and import libraries.

- [ffmpeg.exe](https://github.com/kearcer/ffmpeg_application/blob/main/third_party/ffmpeg/bin/ffmpeg.exe): external tool · Bundled command-line transcoder invoked by the simple demo. · `third_party/ffmpeg/bin/ffmpeg.exe`
- [FFmpeg Headers](https://github.com/kearcer/ffmpeg_application/tree/main/third_party/ffmpeg/include): sdk headers · Vendored API headers for libavformat, libavcodec, libavutil, and related libs. · `third_party/ffmpeg/include`
- [FFmpeg Libs](https://github.com/kearcer/ffmpeg_application/tree/main/third_party/ffmpeg/lib): import libs · Vendored Windows libraries for direct FFmpeg linkage. · `third_party/ffmpeg/lib`

### Media Fixtures

Sample inputs and generated outputs used by the demos.

- [Input Video](https://github.com/kearcer/ffmpeg_application/blob/main/media/input.mp4): fixture · Sample source media used by both demo paths. · `media/input.mp4`
- [CLI Output](https://github.com/kearcer/ffmpeg_application/blob/main/media/output_moved_layout.mp4): artifact · Output produced by the command-line wrapper demo. · `media/output_moved_layout.mp4`
- [Pipeline Output](https://github.com/kearcer/ffmpeg_application/blob/main/media/pipeline_output.mp4): artifact · Output produced by the API pipeline demo. · `media/pipeline_output.mp4`
- [Alt Outputs](https://github.com/kearcer/ffmpeg_application/blob/main/media/pipeline_output_cpp_style.mp4): artifact · Additional generated outputs from pipeline demo variants. · `media/pipeline_output_cpp_style.mp4`

## Connections

- CMake → CLI Transcode: builds · Build system compiles the CLI demo target.
- CMake → Pipeline Demo: builds · Build system compiles the API demo entry point.
- CMake → Transcode Pipeline: links · Build system links pipeline implementation with FFmpeg libs.
- CMake → FFmpeg Headers: uses headers · Build configuration points compilation at vendored FFmpeg headers.
- CMake → FFmpeg Libs: links libs · Build configuration links against vendored FFmpeg import libraries.
- CLI Transcode → ffmpeg.exe: executes · CLI demo shells out to the bundled ffmpeg executable.
- CLI Transcode → Input Video: reads · Consumes the sample input video.
- CLI Transcode → CLI Output: writes · Produces a transcoded output file.
- Pipeline Demo → Transcode Pipeline: orchestrates · Demo entry instantiates and runs the pipeline coordinator.
- Transcode Pipeline → Demuxer: assembles · Coordinator wires the demux stage into the workflow.
- Transcode Pipeline → Decoder: assembles · Coordinator wires the decode stage into the workflow.
- Transcode Pipeline → Frame Prep: assembles · Coordinator wires the frame-preprocess stage into the workflow.
- Transcode Pipeline → Encoder: assembles · Coordinator wires the encode stage into the workflow.
- Transcode Pipeline → Muxer: assembles · Coordinator wires the mux stage into the workflow.
- Demuxer → FFmpeg Helpers: uses · Stage relies on shared FFmpeg boilerplate and error handling.
- Decoder → FFmpeg Helpers: uses · Stage relies on shared FFmpeg boilerplate and error handling.
- Frame Prep → FFmpeg Helpers: uses · Stage relies on shared FFmpeg boilerplate and error handling.
- Encoder → FFmpeg Helpers: uses · Stage relies on shared FFmpeg boilerplate and error handling.
- Muxer → FFmpeg Helpers: uses · Stage relies on shared FFmpeg boilerplate and error handling.
- Transcode Pipeline → Pipeline Logger: logs · Coordinator and stages emit observable state transitions.
- Demuxer → Input Video: reads · Demuxer opens the input media file.
- Muxer → Pipeline Output: writes · Pipeline emits the main output artifact.
- Muxer → Alt Outputs: writes · Pipeline variants emit additional output artifacts.
- Transcode Pipeline → FFmpeg Headers: includes · API pipeline compiles against vendored FFmpeg headers.
- Transcode Pipeline → FFmpeg Libs: links · API pipeline links directly to FFmpeg libraries.
