AVBlocks for Modern C++
AVBlocks Plus provides a modern C++ wrapper around the AVBlocks SDK, offering a fluent API for audio and video transcoding operations. It simplifies common tasks like format conversion, encoding, decoding, and stream manipulation.
- Fluent API: Chain methods together for concise, readable code
- Type Safety: Modern C++ templates and smart pointers
- Exception Handling: Clear error reporting with AVBlocksException
- Cross-Platform: Support for Windows, macOS, and Linux
- Hardware Acceleration: Support for Intel QuickSync, NVIDIA NVENC, and AMD VCE
#include <primo/avblocks/avb++.h>
using namespace primo::codecs;
using namespace primo::avblocks::modern;
int main() {
try {
// Initialize library
TLibrary library;
// Simple file conversion
TTranscoder()
.allowDemoMode(true)
.addInput(TMediaSocket().file("input.mp4"))
.addOutput(TMediaSocket().file("output.wav")
.streamType(StreamType::WAVE)
.addPin(TMediaPin().audioStreamType(StreamType::LPCM)))
.open()
.run()
.close();
return 0;
} catch (const TAVBlocksException& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
return 1;
}
}Decode AAC to PCM audio:
// Create input socket from AAC file
TMediaSocket inputSocket = TMediaSocket()
.file("audio.aac");
// Create output socket for WAV file with LPCM audio
TMediaSocket outputSocket = TMediaSocket()
.file("output.wav")
.streamType(StreamType::WAVE)
.addPin(TMediaPin().audioStreamType(StreamType::LPCM));
// Transcode
TTranscoder()
.allowDemoMode(true)
.addInput(inputSocket)
.addOutput(outputSocket)
.open()
.run()
.close();Encode raw video to H.264:
// Input: raw YUV video
TMediaSocket inputSocket = TMediaSocket()
.file("raw_video.yuv")
.addPin(TMediaPin()
.videoStreamType(StreamType::UncompressedVideo)
.videoWidth(1920)
.videoHeight(1080)
.videoFrameRate(30.0)
.videoColorFormat(ColorFormat::YUV420));
// Output: H.264 in MP4 container
TMediaSocket outputSocket = TMediaSocket()
.file("output.mp4")
.streamType(StreamType::MP4)
.addPin(TMediaPin()
.videoStreamType(StreamType::H264)
.videoWidth(1920)
.videoHeight(1080)
.videoFrameRate(30.0)
.videoBitrate(5000000));
TTranscoder()
.allowDemoMode(true)
.addInput(inputSocket)
.addOutput(outputSocket)
.open()
.run()
.close();AVBlocks provides presets for common output formats:
// Create output from preset
TMediaSocket outputSocket = TMediaSocket()
.file("output.mp4")
.preset("ipad.mp4.h264.720p");
TTranscoder()
.allowDemoMode(true)
.addInput(TMediaSocket().file("input.avi"))
.addOutput(outputSocket)
.open()
.run()
.close();Available presets include:
ipad.mp4.h264.720p- iPad-compatible 720p H.264iphone.mp4.h264.480p- iPhone-compatible 480p H.264dvd.ntsc.4x3.mp2- DVD-Video NTSC formatweb.mp4.h264.720p- Web-optimized 720p H.264- And many more (see Preset documentation)
Get information about a media file:
TMediaInfo info = TMediaInfo()
.addInput(TMediaSocket().file("video.mp4"))
.open();
// Access output sockets with stream information
for (int i = 0; i < info.outputs().count(); ++i) {
MediaSocket* socket = info.outputs().at(i);
// Iterate through pins (streams)
for (int j = 0; j < socket->pins().count(); ++j) {
MediaPin* pin = socket->pins().at(j);
StreamInfo* streamInfo = pin->streamInfo();
if (streamInfo->mediaType() == MediaType::Video) {
auto videoInfo = static_cast<VideoStreamInfo*>(streamInfo);
std::cout << "Video: " << videoInfo->frameWidth()
<< "x" << videoInfo->frameHeight() << std::endl;
}
}
}Enable hardware encoding:
TMediaSocket outputSocket = TMediaSocket()
.file("output.mp4")
.streamType(StreamType::MP4)
.addPin(TMediaPin()
.videoStreamType(StreamType::H264)
.addParam(IntParam(Param::HardwareEncoder,
HardwareEncoder::Auto)));
// Or configure globally
TLibrary::config()->hardware()->setIntelMedia(true);
TLibrary::config()->hardware()->setNvenc(true);The modern API uses exceptions for error handling:
try {
TTranscoder transcoder = TTranscoder()
.addInput(TMediaSocket().file("input.mp4"))
.addOutput(TMediaSocket().file("output.wav"))
.open();
transcoder.run();
transcoder.close();
} catch (const TAVBlocksException& ex) {
std::cerr << "AVBlocks error: " << ex.what() << std::endl;
// Access detailed error information
const auto* errorInfo = ex.errorInfo();
if (errorInfo) {
std::cerr << "Facility: " << errorInfo->facility() << std::endl;
std::cerr << "Code: " << errorInfo->code() << std::endl;
}
} catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}For advanced scenarios, you can push/pull media samples:
// Create decoder transcoder - input from file, output PCM without file
TTranscoder decoder = TTranscoder()
.allowDemoMode(true)
.addInput(TMediaSocket().file("input.aac"))
.addOutput(TMediaSocket()
.streamType(StreamType::LPCM)
.addPin(TMediaPin()
.audioStreamType(StreamType::LPCM)
.channels(2)
.sampleRate(48000)
.bitsPerSample(16)))
.open();
// Create WAV writer transcoder - input PCM without file, output to file
TTranscoder wavWriter = TTranscoder()
.allowDemoMode(true)
.addInput(TMediaSocket()
.streamType(StreamType::LPCM)
.addPin(TMediaPin()
.audioStreamType(StreamType::LPCM)
.channels(2)
.sampleRate(48000)
.bitsPerSample(16)))
.addOutput(TMediaSocket()
.file("output.wav")
.streamType(StreamType::WAVE)
.addPin(TMediaPin()
.audioStreamType(StreamType::LPCM)
.channels(2)
.sampleRate(48000)
.bitsPerSample(16)))
.open();
// Pull-push decoding loop
int32_t outputIndex = 0;
TMediaSample pcmSample;
bool decoderEos = false;
while (!decoderEos) {
// Pull PCM sample from decoder
if (decoder.pull(outputIndex, pcmSample)) {
// Push PCM sample to WAV writer
wavWriter.push(0, pcmSample);
continue;
}
// Check for end of stream
const auto* error = decoder.error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == CodecError::EOS) {
// Push null sample to signal EOS to WAV writer
TMediaSample nullSample;
wavWriter.push(0, nullSample);
decoderEos = true;
}
}
decoder.close();
wavWriter.close();- TLibrary: Initialize/shutdown AVBlocks, manage licensing
- TTranscoder/TTranscoderW: Main transcoding engine (ANSI/Wide character variants)
- TMediaSocket/TMediaSocketW: Input/output endpoint (file, stream, or elementary)
- TMediaPin: Elementary stream within a socket
- TMediaInfo: Analyze media files
- TMediaSample: Container for media data
- TMediaBuffer: Raw media data buffer
- StreamType: Container formats (MP4, AVI, WAV, etc.)
- ColorFormat: Video color formats (YUV420, RGB, etc.)
- ScanType: Progressive or interlaced video
- AudioChannelFlags: Audio channel layouts
Configure encoding/decoding behavior:
TMediaPin pin = TMediaPin()
.addParam(IntParam(Param::Video::Bitrate, 5000000))
.addParam(IntParam(Param::Encoder::Video::H264::Profile,
H264Profile::High))
.addParam(IntParam(Param::Encoder::Video::H264::Level, 41));- Use
TMediaSocketWandTTranscoderWclasses for wide-character (Unicode) file paths - Link against
AVBlocks64.lib
- Use
TMediaSocketandTTranscoderclasses (ANSI/UTF-8 paths) - Link against
libAVBlocks.dylib
- Use
TMediaSocketandTTranscoderclasses (ANSI/UTF-8 paths) - Link against
libAVBlocks64.so
See Download Core and Assets on macOS
See Setup for macOS
See Build on macOS
See README in the samples subdirectory.
See Download Core and Assets on Linux
See Setup for Linux
See Build on Linux
See README in the samples subdirectory.
See Download Core and Assets on Windows
See Build on Windows
See README in the samples subdirectory.
See License Options for details.
We offer discounts for:
- Competitive product
- Startup
- Educational institution
- Open source project