|
| 1 | +# GStreamer Video Recorder |
| 2 | + |
| 3 | +A Holoscan application that demonstrates video recording using the GStreamer encoding pipeline. |
| 4 | + |
| 5 | +## Description |
| 6 | + |
| 7 | +This application showcases how to: |
| 8 | +- Generate video frames in Holoscan using the pattern generator |
| 9 | +- Feed video frames to GStreamer for encoding |
| 10 | +- Record encoded video to files in various formats (MP4, MKV) |
| 11 | +- Use different video codecs (H.264, H.265, and other GStreamer-supported codecs) |
| 12 | +- Support both host and CUDA device memory for zero-copy operation |
| 13 | + |
| 14 | +## Requirements |
| 15 | + |
| 16 | +- NVIDIA Holoscan SDK |
| 17 | +- GStreamer 1.0 with the following plugins: |
| 18 | + - gstreamer1.0-plugins-base (videoconvert for host memory support) |
| 19 | + - gstreamer1.0-plugins-bad (cudaconvert, nvh264enc, nvh265enc for NVIDIA hardware encoding) |
| 20 | + - gstreamer1.0-plugins-good (mp4mux, matroskamux for container formats) |
| 21 | + - gstreamer1.0-plugins-ugly (x264enc for CPU-based H.264 encoding) |
| 22 | + - Additional codecs available through gstreamer1.0-libav if needed |
| 23 | + |
| 24 | +## Building |
| 25 | + |
| 26 | +### Option 1: Containerized Build (Recommended) |
| 27 | +No setup required - all dependencies are included in the container: |
| 28 | + |
| 29 | +```bash |
| 30 | +./holohub build gst_video_recorder |
| 31 | +``` |
| 32 | + |
| 33 | +### Option 2: Local Build |
| 34 | +For faster builds and easier debugging. First install dependencies: |
| 35 | + |
| 36 | +```bash |
| 37 | +# From the gst_video_recorder directory |
| 38 | +./install_deps.sh |
| 39 | + |
| 40 | +# Then build locally |
| 41 | +./holohub build --local gst_video_recorder |
| 42 | +``` |
| 43 | + |
| 44 | +The `install_deps.sh` script installs: |
| 45 | +- pkg-config (required for CMake) |
| 46 | +- GStreamer development libraries |
| 47 | +- All necessary GStreamer plugins for encoding |
| 48 | + |
| 49 | +## Usage |
| 50 | + |
| 51 | +```bash |
| 52 | +gst-video-recorder [OPTIONS] |
| 53 | +``` |
| 54 | + |
| 55 | +### Options |
| 56 | + |
| 57 | +- `-o, --output <filename>` - Output video filename (default: output.mp4) |
| 58 | + - Supported formats: .mp4, .mkv |
| 59 | + - If no extension, defaults to .mp4 |
| 60 | +- `-e, --encoder <name>` - Encoder base name (default: nvh264) |
| 61 | + - Examples: nvh264, nvh265, x264, x265 |
| 62 | + - Note: 'enc' suffix is automatically appended |
| 63 | +- `-c, --count <number>` - Number of frames to generate (default: unlimited) |
| 64 | +- `-w, --width <pixels>` - Frame width (default: 1920) |
| 65 | +- `-h, --height <pixels>` - Frame height (default: 1080) |
| 66 | +- `-f, --framerate <rate>` - Frame rate as fraction or decimal (default: 30/1) |
| 67 | + - Examples: '30/1', '30000/1001', '29.97', '60' |
| 68 | + - Use '0/1' for live mode (no throttling, real-time timestamps) |
| 69 | +- `--pattern <type>` - Pattern type (default: 0) |
| 70 | + - 0 = animated gradient |
| 71 | + - 1 = animated checkerboard |
| 72 | + - 2 = color bars (SMPTE style) |
| 73 | +- `--storage <type>` - Memory storage type (default: 1) |
| 74 | + - 0 = host memory |
| 75 | + - 1 = device/CUDA memory |
| 76 | +- `--property <key=value>` - Set encoder property (can be used multiple times) |
| 77 | + - Examples: --property bitrate=8000 --property preset=1 |
| 78 | + - Property types are automatically detected and converted |
| 79 | +- `--help` - Show help message |
| 80 | + |
| 81 | +### Examples |
| 82 | + |
| 83 | +#### Record 10 seconds of video at 30fps (300 frames) |
| 84 | + |
| 85 | +```bash |
| 86 | +gst-video-recorder --count 300 -o video.mp4 |
| 87 | +``` |
| 88 | + |
| 89 | +#### Record high quality H.265 video |
| 90 | + |
| 91 | +```bash |
| 92 | +gst-video-recorder --count 300 --encoder nvh265 --property bitrate=10000 -o video.mp4 |
| 93 | +``` |
| 94 | + |
| 95 | +#### Record 720p video |
| 96 | + |
| 97 | +```bash |
| 98 | +gst-video-recorder --count 300 --width 1280 --height 720 -o video_720p.mp4 |
| 99 | +``` |
| 100 | + |
| 101 | +#### Record using host memory (CPU) |
| 102 | + |
| 103 | +```bash |
| 104 | +gst-video-recorder --count 300 --storage 0 --encoder x264 -o video.mp4 |
| 105 | +``` |
| 106 | + |
| 107 | +#### Record with H.265 to MKV container |
| 108 | + |
| 109 | +```bash |
| 110 | +gst-video-recorder --count 300 --encoder nvh265 -o video.mkv |
| 111 | +``` |
| 112 | + |
| 113 | +#### Record animated checkerboard pattern |
| 114 | + |
| 115 | +```bash |
| 116 | +gst-video-recorder --count 300 --pattern 1 -o checkerboard.mp4 |
| 117 | +``` |
| 118 | + |
| 119 | +#### Record with custom encoder properties |
| 120 | + |
| 121 | +```bash |
| 122 | +gst-video-recorder --count 300 --property bitrate=8000 --property preset=1 --property gop-size=30 -o custom.mp4 |
| 123 | +``` |
| 124 | + |
| 125 | +#### Record with NTSC framerate (29.97 fps) |
| 126 | + |
| 127 | +```bash |
| 128 | +gst-video-recorder --count 300 --framerate 30000/1001 -o ntsc.mp4 |
| 129 | +``` |
| 130 | + |
| 131 | +## Architecture |
| 132 | + |
| 133 | +The application consists of two main components: |
| 134 | + |
| 135 | +1. **PatternGenOperator**: Generates animated test patterns as Holoscan entities with tensors |
| 136 | +2. **GstVideoRecorderOperator**: Receives video frames, manages the GStreamer pipeline, and handles encoding |
| 137 | + |
| 138 | +### Pipeline Flow |
| 139 | + |
| 140 | +``` |
| 141 | +PatternGenOperator → GstVideoRecorderOperator → GStreamer Encoding Pipeline → File |
| 142 | +``` |
| 143 | + |
| 144 | +The GStreamer encoding pipeline is automatically constructed based on the encoder and file format: |
| 145 | + |
| 146 | +- **Pipeline structure**: `[converter] ! [encoder]enc ! [parser] ! [muxer] ! filesink` |
| 147 | +- **Converter**: Automatically selected based on memory type (videoconvert for host, cudaconvert for device) |
| 148 | +- **Encoder**: Specified via `--encoder` option (nvh264, nvh265, x264, x265, etc.) |
| 149 | +- **Parser**: Automatically determined from encoder (h264parse, h265parse, etc.) |
| 150 | +- **Muxer**: Automatically determined from file extension (mp4mux for .mp4, matroskamux for .mkv) |
| 151 | + |
| 152 | +Example pipelines: |
| 153 | + |
| 154 | +- **NVIDIA H.264 to MP4**: `cudaconvert ! nvh264enc ! h264parse ! mp4mux ! filesink` |
| 155 | +- **NVIDIA H.265 to MKV**: `cudaconvert ! nvh265enc ! h265parse ! matroskamux ! filesink` |
| 156 | +- **CPU x264 to MP4**: `videoconvert ! x264enc ! h264parse ! mp4mux ! filesink` |
| 157 | + |
| 158 | +## Performance |
| 159 | + |
| 160 | +The application supports both host and device (CUDA) memory: |
| 161 | + |
| 162 | +- **Device memory** (`--storage 1`, default): Zero-copy operation for better performance when using NVIDIA hardware encoders (nvh264enc, nvh265enc) |
| 163 | +- **Host memory** (`--storage 0`): Required for CPU encoders (x264, x265) but involves memory copies |
| 164 | + |
| 165 | +## Notes |
| 166 | + |
| 167 | +- The pattern generator supports three test patterns: |
| 168 | + - Animated gradient (default): Colorful sine wave patterns |
| 169 | + - Animated checkerboard: Moving checkerboard with variable square size |
| 170 | + - Color bars: SMPTE-style color bars (7 colors) |
| 171 | +- To use your own video source, replace `PatternGenOperator` with your video capture operator |
| 172 | +- The application waits for encoding to complete before exiting to ensure proper file finalization |
| 173 | +- EOS (End-Of-Stream) signal is sent automatically when recording completes |
| 174 | +- Video parameters (width, height, format, storage) are automatically detected from incoming frames |
| 175 | + |
| 176 | +## See Also |
| 177 | + |
| 178 | +- `holopattern_to_gst` - Similar application that can output to any GStreamer pipeline |
| 179 | +- GStreamer documentation: https://gstreamer.freedesktop.org/documentation/ |
| 180 | + |
| 181 | + |
0 commit comments