AVBlocks - Audio SDK - Video SDK - C++ SDK - CLI Samples
- API Docs — Online API reference for the AVBlocks C++ SDK
- Wiki — Documentation and guides
- Blog — News and updates
Download and install the AVBlocks demo version on your platform. The extracted files will be placed under the sdk/ directory of this repository.
# select version and platform
tag="v3.4.0-demo.1"
platform="linux"
# download
mkdir -p ./sdk
cd ./sdk
# sdk
curl \
--location \
--output ./avblocks-$tag-$platform.tar.gz \
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.tar.gz
# sha256 checksum
curl \
--location \
--output ./avblocks-$tag-$platform.tar.gz.sha256 \
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.tar.gz.sha256
# verify sha256 checksum
shasum --check ./avblocks-$tag-$platform.tar.gz.sha256
# extract
tar -xvf avblocks-$tag-$platform.tar.gz
cd ..# select version and platform
tag="v3.4.0-demo.1"
platform="darwin"
# download
mkdir -p ./sdk
cd ./sdk
# sdk
curl \
--location \
--output ./avblocks-$tag-$platform.zip \
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.zip
# sha256 checksum
curl \
--location \
--output ./avblocks-$tag-$platform.zip.sha256 \
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.zip.sha256
# verify sha256 checksum
shasum --check ./avblocks-$tag-$platform.zip.sha256
# unzip
unzip avblocks-$tag-$platform.zip
cd ..Scripts are PowerShell
# select version and platform
$tag='v3.4.0-demo.1'
$platform='windows'
# download
new-item -Force -ItemType Directory ./sdk
cd ./sdk
# sdk
curl.exe `
--location `
--output ./avblocks-$tag-$platform.zip `
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.zip
# sha256 checksum
curl.exe `
--location `
--output ./avblocks-$tag-$platform.zip.sha256 `
https://github.com/avblocks/avblocks-core/releases/download/$tag/avblocks-$tag-$platform.zip.sha256
# verify checksum
$downloadedHash = (Get-FileHash -Algorithm SHA256 ./avblocks-$tag-$platform.zip).Hash.ToLower()
$expectedHash = (Get-Content ./avblocks-$tag-$platform.zip.sha256).Split(' ')[0].ToLower()
if ($downloadedHash -eq $expectedHash) { Write-Host "Checksum OK!"; } else { Write-Host "Checksum failed!"; }
# unzip
expand-archive -Force -Path avblocks-$tag-$platform.zip -DestinationPath .
cd ..For more details, see the platform-specific setup guides in docs/.
AVBlocks must be initialized before use and shut down when done:
#include <primo/avblocks/avb.h>
int main() {
// Initialize AVBlocks
primo::avblocks::Library::initialize();
// Set license (optional for demo)
// primo::avblocks::Library::setLicense("YOUR-LICENSE-KEY");
// Enable demo mode for testing without license
transcoder->setAllowDemoMode(true);
// Your code here
// Shutdown AVBlocks
primo::avblocks::Library::shutdown();
return 0;
}A MediaSocket represents an input or output container/file with specific media parameters. It acts as a collection of media streams (via MediaPin objects) and defines the container format.
// Create a media socket
primo::ref<MediaSocket> socket(Library::createMediaSocket());
// Set file path
socket->setFile(primo::ustring("video.mp4"));
// Set container type
socket->setStreamType(StreamType::MP4);
// Create socket from preset
auto socket = primo::make_ref(Library::createMediaSocket("mp4.h264.aac"));A MediaPin represents a single media stream (audio or video) within a MediaSocket. Each pin has a StreamInfo object that describes the stream's properties (codec, resolution, sample rate, etc.).
// Create a pin for video
primo::ref<MediaPin> pin(Library::createMediaPin());
// Create and configure video stream info
primo::ref<VideoStreamInfo> vsi(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::H264);
vsi->setFrameWidth(1920);
vsi->setFrameHeight(1080);
vsi->setFrameRate(30.0);
// Attach stream info to pin
pin->setStreamInfo(vsi.get());
// Add pin to socket
socket->pins()->add(pin.get());
// Access pins from a socket
MediaPinList* pins = socket->pins();
int pinCount = pins->count();
MediaPin* firstPin = pins->at(0);StreamInfo and its subclasses (VideoStreamInfo, AudioStreamInfo) describe the properties of a media stream:
// Video stream info
primo::ref<VideoStreamInfo> vsi(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::H264);
vsi->setStreamSubType(StreamSubType::AVC_Annex_B);
vsi->setFrameWidth(1920);
vsi->setFrameHeight(1080);
vsi->setFrameRate(30.0);
vsi->setColorFormat(ColorFormat::YUV420);
vsi->setScanType(ScanType::Progressive);
vsi->setBitrate(2000000); // 2 Mbps
// Audio stream info
primo::ref<AudioStreamInfo> asi(Library::createAudioStreamInfo());
asi->setStreamType(StreamType::AAC);
asi->setSampleRate(44100);
asi->setChannels(2);
asi->setBitsPerSample(16);
asi->setBitrate(128000); // 128 kbps
// Get info properties
MediaType::Enum mediaType = si->mediaType(); // Video or Audio
StreamType::Enum streamType = si->streamType();
double duration = si->duration();
int id = si->ID();MediaInfo is used to probe media files and extract information about containers, streams, and metadata without performing transcoding.
// Create MediaInfo object
primo::ref<MediaInfo> info(Library::createMediaInfo());
// Set input file
info->inputs()->at(0)->setFile(primo::ustring("video.mp4"));
// Open and analyze the file
if (info->open()) {
// Access container information
MediaSocket* socket = info->outputs()->at(0);
StreamType::Enum containerType = socket->streamType();
// Iterate through streams
for (int i = 0; i < socket->pins()->count(); i++) {
MediaPin* pin = socket->pins()->at(i);
StreamInfo* si = pin->streamInfo();
if (si->mediaType() == MediaType::Video) {
VideoStreamInfo* vsi = static_cast<VideoStreamInfo*>(si);
int width = vsi->frameWidth();
int height = vsi->frameHeight();
double fps = vsi->frameRate();
double duration = vsi->duration();
ColorFormat::Enum colorFormat = vsi->colorFormat();
ScanType::Enum scanType = vsi->scanType();
}
else if (si->mediaType() == MediaType::Audio) {
AudioStreamInfo* asi = static_cast<AudioStreamInfo*>(si);
int sampleRate = asi->sampleRate();
int channels = asi->channels();
int bitsPerSample = asi->bitsPerSample();
int bitrate = asi->bitrate();
}
}
}
// Create input socket from MediaInfo
primo::ref<MediaSocket> inputSocket(Library::createMediaSocket(info.get()));The Transcoder class performs media conversion between input and output sockets. It supports three modes of operation:
- Run Mode: Simple one-shot transcoding -
transcoder->run() - Push Mode: Feed data to the transcoder manually -
transcoder->push() - Pull Mode: Extract encoded/decoded data frame by frame -
transcoder->pull()
primo::ref<Transcoder> transcoder(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
printError("Transcoder open", transcoder->error());
return false;
}MediaSample represents a single unit of media data (audio frame or video frame) with timing information. MediaBuffer holds the actual media data.
// Create a media sample
primo::ref<MediaSample> sample(Library::createMediaSample());
// Create and attach a buffer
primo::ref<MediaBuffer> buffer(Library::createMediaBuffer(dataSize));
uint8_t* data = buffer->start();
memcpy(data, sourceData, dataSize);
buffer->setData(0, dataSize);
sample->setBuffer(buffer.get());
// Set timestamps (in seconds)
sample->setStartTime(0.0);
// Attach external buffer without copy
std::vector<uint8_t> externalData(1024);
buffer->attach(externalData.data(), externalData.size(), true);
// Read buffer data
const uint8_t* readData = sample->buffer()->data();
int readSize = sample->buffer()->dataSize();Extract stream information from a media file:
#include <primo/avblocks/avb.h>
#include <primo/platform/reference++.h>
using namespace primo::avblocks;
using namespace primo::codecs;
primo::ref<MediaInfo> info(Library::createMediaInfo());
info->inputs()->at(0)->setFile(primo::ustring("input.mp4"));
if (info->open()) {
MediaSocket* socket = info->outputs()->at(0);
// Container type
StreamType::Enum containerType = socket->streamType();
std::cout << "Container: " << getStreamTypeName(containerType) << std::endl;
// Iterate through all streams
for (int i = 0; i < socket->pins()->count(); i++) {
MediaPin* pin = socket->pins()->at(i);
StreamInfo* si = pin->streamInfo();
std::cout << "Stream #" << i << " " << getMediaTypeName(si->mediaType()) << std::endl;
if (si->mediaType() == MediaType::Video) {
VideoStreamInfo* vsi = static_cast<VideoStreamInfo*>(si);
std::cout << " Frame size: " << vsi->frameWidth() << "x" << vsi->frameHeight() << std::endl;
std::cout << " Frame rate: " << vsi->frameRate() << std::endl;
std::cout << " Duration: " << vsi->duration() << " seconds" << std::endl;
std::cout << " Bitrate: " << vsi->bitrate() << std::endl;
std::cout << " Color format: " << getColorFormatName(vsi->colorFormat()) << std::endl;
std::cout << " Scan type: " << getScanTypeName(vsi->scanType()) << std::endl;
}
else if (si->mediaType() == MediaType::Audio) {
AudioStreamInfo* asi = static_cast<AudioStreamInfo*>(si);
std::cout << " Sample rate: " << asi->sampleRate() << std::endl;
std::cout << " Channels: " << asi->channels() << std::endl;
std::cout << " Bits per sample: " << asi->bitsPerSample() << std::endl;
std::cout << " Bitrate: " << asi->bitrate() << std::endl;
std::cout << " Duration: " << asi->duration() << " seconds" << std::endl;
}
}
}Decode H.264/AVC video to raw YUV format using simple run mode:
using namespace primo::avblocks;
using namespace primo::codecs;
// Use MediaInfo to get input properties
primo::ref<MediaInfo> info(Library::createMediaInfo());
info->inputs()->at(0)->setFile(primo::ustring("input.h264"));
if (!info->open()) {
printError("MediaInfo open", info->error());
return false;
}
// Create input socket from MediaInfo
primo::ref<MediaSocket> inputSocket(Library::createMediaSocket(info.get()));
// Create output socket for YUV
auto outputSocket = primo::make_ref(Library::createMediaSocket());
outputSocket->setFile(primo::ustring("output.yuv"));
outputSocket->setStreamType(StreamType::UncompressedVideo);
auto pin = primo::make_ref(Library::createMediaPin());
auto vsi = primo::make_ref(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::UncompressedVideo);
vsi->setColorFormat(ColorFormat::YUV420);
pin->setStreamInfo(vsi.get());
outputSocket->pins()->add(pin.get());
// Create and configure transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
printError("Transcoder open", transcoder->error());
return false;
}
// Simple run - transcodes entire file
if (!transcoder->run()) {
printError("Transcoder run", transcoder->error());
return false;
}
transcoder->close();Decode video and extract frames one by one:
// Setup input and output sockets (same as run mode)
// ...
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Pull decoded frames one by one
int32_t outputIndex = 0;
auto sample = primo::make_ref(Library::createMediaSample());
while (transcoder->pull(outputIndex, sample.get())) {
// Process decoded frame
MediaBuffer* buffer = sample->buffer();
const uint8_t* data = buffer->data();
int dataSize = buffer->dataSize();
// Write to file or process further
outputFile.write((const char*)data, dataSize);
}
// Check if we reached end of stream
const primo::error::ErrorInfo* error = transcoder->error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == primo::codecs::CodecError::EOS) {
// Successfully reached end of stream
std::cout << "Success" << std::endl;
}
else {
printError("Transcoder pull", error);
}
transcoder->close();Encode raw YUV video to H.264/AVC:
// Create input socket for YUV
auto inputSocket = primo::make_ref(Library::createMediaSocket());
inputSocket->setStreamType(StreamType::UncompressedVideo);
inputSocket->setFile(primo::ustring("input.yuv"));
auto inPin = primo::make_ref(Library::createMediaPin());
auto inVsi = primo::make_ref(Library::createVideoStreamInfo());
inVsi->setStreamType(StreamType::UncompressedVideo);
inVsi->setColorFormat(ColorFormat::YUV420);
inVsi->setFrameWidth(1920);
inVsi->setFrameHeight(1080);
inVsi->setFrameRate(30.0);
inVsi->setScanType(ScanType::Progressive);
inPin->setStreamInfo(inVsi.get());
inputSocket->pins()->add(inPin.get());
// Create output socket for H.264
auto outputSocket = primo::make_ref(Library::createMediaSocket());
outputSocket->setFile(primo::ustring("output.h264"));
outputSocket->setStreamType(StreamType::H264);
auto outPin = primo::make_ref(Library::createMediaPin());
auto outVsi = primo::make_ref(Library::createVideoStreamInfo());
outVsi->setStreamType(StreamType::H264);
outVsi->setStreamSubType(StreamSubType::AVC_Annex_B);
outPin->setStreamInfo(outVsi.get());
outputSocket->pins()->add(outPin.get());
// Create and run transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
if (!transcoder->run()) {
return false;
}
transcoder->close();Encode video and extract encoded packets frame by frame:
// Setup input and output sockets
// ...
std::ofstream outfile("output.h264", std::ios::binary);
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Pull encoded samples
int32_t outputIndex = 0;
auto sample = primo::make_ref(Library::createMediaSample());
while (transcoder->pull(outputIndex, sample.get())) {
// Write encoded data
outfile.write((const char*)sample->buffer()->data(),
sample->buffer()->dataSize());
}
const primo::error::ErrorInfo* error = transcoder->error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == primo::codecs::CodecError::EOS) {
// Success
}
transcoder->close();
outfile.close();Feed raw frames to encoder manually:
// Output socket for H.264
// ...
// Input socket without file (we'll push data manually)
auto inputSocket = primo::make_ref(Library::createMediaSocket());
inputSocket->setStreamType(StreamType::UncompressedVideo);
auto pin = primo::make_ref(Library::createMediaPin());
auto vsi = primo::make_ref(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::UncompressedVideo);
vsi->setColorFormat(ColorFormat::YUV420);
vsi->setFrameWidth(1920);
vsi->setFrameHeight(1080);
vsi->setFrameRate(30.0);
vsi->setScanType(ScanType::Progressive);
pin->setStreamInfo(vsi.get());
inputSocket->pins()->add(pin.get());
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Push frames manually
auto sample = primo::make_ref(Library::createMediaSample());
for (int frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
// Read or generate frame data
std::vector<uint8_t> frameData = getFrameData(frameIndex);
auto buffer = primo::make_ref(Library::createMediaBuffer());
buffer->attach(frameData.data(), frameData.size(), true);
sample->setBuffer(buffer.get());
// Set presentation timestamp (required)
sample->setStartTime(frameIndex / 30.0); // For 30 fps
if (!transcoder->push(0, sample.get())) {
printError("Transcoder push", transcoder->error());
break;
}
}
// Flush remaining data
if (!transcoder->flush()) {
printError("Transcoder flush", transcoder->error());
}
transcoder->close();AVBlocks provides presets for common encoding scenarios:
// Create output with preset name
auto outputSocket = primo::make_ref(Library::createMediaSocket("mp4.h264.aac"));
outputSocket->setFile(primo::ustring("output.mp4"));
// Or use specific preset
auto outputSocket = primo::make_ref(Library::createMediaSocket("ipad.mp4.h264.576p"));
outputSocket->setFile(primo::ustring("output.mp4"));
// Add to transcoder
transcoder->outputs()->add(outputSocket.get());Common presets:
- MP4:
mp4.h264.aac- H.264 video + AAC audio - iPad:
ipad.mp4.h264.576p,ipad.mp4.h264.720p - iPhone:
iphone.mp4.h264.480p - Android:
android-phone.mp4.h264.360p,android-phone.mp4.h264.720p,android-tablet.mp4.h264.720p - DVD:
dvd.pal.4x3.mp2,dvd.ntsc.16x9.mp2 - WebM:
webm.vp8.vorbis,android-tablet.webm.vp8.720p - Apple TV:
appletv.h264.480p,appletv.h264.720p - VCD:
vcd.pal,vcd.ntsc
Decode AAC ADTS to raw PCM WAV:
// Create input socket
auto inputSocket = primo::make_ref(Library::createMediaSocket());
inputSocket->setFile(primo::ustring("input.aac"));
// Create output socket for WAV
auto outputSocket = primo::make_ref(Library::createMediaSocket());
outputSocket->setFile(primo::ustring("output.wav"));
outputSocket->setStreamType(StreamType::WAVE);
auto pin = primo::make_ref(Library::createMediaPin());
auto asi = primo::make_ref(Library::createAudioStreamInfo());
asi->setStreamType(StreamType::LPCM);
pin->setStreamInfo(asi.get());
outputSocket->pins()->add(pin.get());
// Setup and run transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (transcoder->open()) {
transcoder->run();
transcoder->close();
}Decode AAC and extract decoded PCM samples:
// Setup input and output sockets
// ...
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Pull decoded audio samples
int32_t outputIndex = 0;
auto sample = primo::make_ref(Library::createMediaSample());
while (transcoder->pull(outputIndex, sample.get())) {
// Process decoded audio
outfile.write((const char*)sample->buffer()->data(),
sample->buffer()->dataSize());
}
const primo::error::ErrorInfo* error = transcoder->error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == primo::codecs::CodecError::EOS) {
// Success
}
transcoder->close();Encode WAV file to MP3:
// Input: WAV file
auto inputSocket = primo::make_ref(Library::createMediaSocket());
inputSocket->setFile(primo::ustring("input.wav"));
// Output: MP3
auto outputSocket = primo::make_ref(Library::createMediaSocket());
outputSocket->setFile(primo::ustring("output.mp3"));
outputSocket->setStreamType(StreamType::MPEG_Audio);
outputSocket->setStreamSubType(StreamSubType::MPEG_Audio_Layer3);
auto pin = primo::make_ref(Library::createMediaPin());
auto asi = primo::make_ref(Library::createAudioStreamInfo());
asi->setStreamType(StreamType::MPEG_Audio);
asi->setStreamSubType(StreamSubType::MPEG_Audio_Layer3);
// Optional: set bitrate (default is 128000)
// asi->setBitrate(192000);
pin->setStreamInfo(asi.get());
outputSocket->pins()->add(pin.get());
// Setup and run transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (transcoder->open()) {
transcoder->run();
transcoder->close();
}Encode WAV to MP3 using pull mode:
// Setup input and output sockets
// ...
std::ofstream outfile("output.mp3", std::ios::binary);
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Pull encoded samples
int32_t outputIndex = 0;
auto sample = primo::make_ref(Library::createMediaSample());
while (transcoder->pull(outputIndex, sample.get())) {
outfile.write((const char*)sample->buffer()->data(),
sample->buffer()->dataSize());
}
const primo::error::ErrorInfo* error = transcoder->error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == primo::codecs::CodecError::EOS) {
// Success
}
transcoder->close();Feed audio samples to encoder manually:
// Output socket for AAC/MP3
// ...
// Input socket without file
auto inputSocket = primo::make_ref(Library::createMediaSocket());
auto pin = primo::make_ref(Library::createMediaPin());
auto asi = primo::make_ref(Library::createAudioStreamInfo());
asi->setStreamType(StreamType::LPCM);
asi->setSampleRate(44100);
asi->setChannels(2);
asi->setBitsPerSample(16);
pin->setStreamInfo(asi.get());
inputSocket->pins()->add(pin.get());
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Push audio samples
auto sample = primo::make_ref(Library::createMediaSample());
// Read audio data in chunks
while (readAudioData(audioBuffer, bufferSize)) {
auto buffer = primo::make_ref(Library::createMediaBuffer(bufferSize));
memcpy(buffer->start(), audioBuffer, bufferSize);
buffer->setData(0, bufferSize);
sample->setBuffer(buffer.get());
if (!transcoder->push(0, sample.get())) {
break;
}
}
transcoder->flush();
transcoder->close();Create a video slideshow from a sequence of images:
// Use MediaInfo to get properties of first image
auto info = primo::make_ref(Library::createMediaInfo());
std::string firstImage = inputDir + "/image_0000.jpeg";
info->inputs()->at(0)->setFile(primo::ustring(firstImage));
if (!info->open()) {
return false;
}
// Create input socket without file (we'll push images)
auto inputSocket = primo::make_ref(Library::createMediaSocket());
auto pin = primo::make_ref(Library::createMediaPin());
// Clone video info from first image and set frame rate
auto vsi = primo::make_ref(
(VideoStreamInfo*)info->outputs()->at(0)->pins()->at(0)->streamInfo()->clone()
);
vsi->setFrameRate(25.0); // 25 fps slideshow
pin->setStreamInfo(vsi.get());
inputSocket->pins()->add(pin.get());
// Create output socket with preset
auto outputSocket = primo::make_ref(Library::createMediaSocket("mp4.h264.aac"));
outputSocket->setFile(primo::ustring("output.mp4"));
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
return false;
}
// Push images
auto sample = primo::make_ref(Library::createMediaSample());
for (int i = 0; i < imageCount; i++) {
// Read image file into buffer
std::string imgFile = inputDir + "/image_" + std::to_string(i) + ".jpeg";
std::vector<uint8_t> imageData = readFileBytes(imgFile);
auto buffer = primo::make_ref(Library::createMediaBuffer());
buffer->attach(imageData.data(), imageData.size(), true);
sample->setBuffer(buffer.get());
// Set correct timestamp for video frame (required)
sample->setStartTime(i / 25.0);
if (!transcoder->push(0, sample.get())) {
break;
}
}
transcoder->flush();
transcoder->close();Extract audio and video streams from MP4 container:
// Use MediaInfo to analyze input
auto info = primo::make_ref(Library::createMediaInfo());
info->inputs()->at(0)->setFile(primo::ustring("input.mp4"));
if (!info->open()) {
return false;
}
// Find audio and video streams
int audioStreamIndex = -1;
int videoStreamIndex = -1;
MediaSocket* socket = info->outputs()->at(0);
for (int i = 0; i < socket->pins()->count(); i++) {
MediaPin* pin = socket->pins()->at(i);
if (pin->streamInfo()->mediaType() == MediaType::Audio) {
audioStreamIndex = i;
}
else if (pin->streamInfo()->mediaType() == MediaType::Video) {
videoStreamIndex = i;
}
}
// Create input socket
auto inputSocket = primo::make_ref(Library::createMediaSocket(info.get()));
// Create separate output sockets for audio and video
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->inputs()->add(inputSocket.get());
if (videoStreamIndex >= 0) {
auto videoOutput = primo::make_ref(Library::createMediaSocket());
videoOutput->setFile(primo::ustring("video.mp4"));
videoOutput->setStreamType(StreamType::MP4);
auto videoPin = primo::make_ref(Library::createMediaPin());
videoPin->setStreamInfo(
socket->pins()->at(videoStreamIndex)->streamInfo()
);
videoOutput->pins()->add(videoPin.get());
transcoder->outputs()->add(videoOutput.get());
}
if (audioStreamIndex >= 0) {
auto audioOutput = primo::make_ref(Library::createMediaSocket());
audioOutput->setFile(primo::ustring("audio.mp4"));
audioOutput->setStreamType(StreamType::MP4);
auto audioPin = primo::make_ref(Library::createMediaPin());
audioPin->setStreamInfo(
socket->pins()->at(audioStreamIndex)->streamInfo()
);
audioOutput->pins()->add(audioPin.get());
transcoder->outputs()->add(audioOutput.get());
}
// Setup transcoder and process
transcoder->setAllowDemoMode(true);
if (transcoder->open()) {
transcoder->run();
transcoder->close();
}Combine separate audio and video streams into single MP4:
// Create first input for video
auto videoInput = primo::make_ref(Library::createMediaSocket());
videoInput->setFile(primo::ustring("video.mp4"));
// Create second input for audio
auto audioInput = primo::make_ref(Library::createMediaSocket());
audioInput->setFile(primo::ustring("audio.mp4"));
// Create output socket
auto outputSocket = primo::make_ref(Library::createMediaSocket());
outputSocket->setFile(primo::ustring("output.mp4"));
outputSocket->setStreamType(StreamType::MP4);
// Add both video and audio pins to output
auto videoPin = primo::make_ref(Library::createMediaPin());
auto vsi = primo::make_ref(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::H264);
videoPin->setStreamInfo(vsi.get());
outputSocket->pins()->add(videoPin.get());
auto audioPin = primo::make_ref(Library::createMediaPin());
auto asi = primo::make_ref(Library::createAudioStreamInfo());
asi->setStreamType(StreamType::AAC);
audioPin->setStreamInfo(asi.get());
outputSocket->pins()->add(audioPin.get());
// Setup transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(videoInput.get());
transcoder->inputs()->add(audioInput.get());
transcoder->outputs()->add(outputSocket.get());
if (transcoder->open()) {
transcoder->run();
transcoder->close();
}Take an MP4 input and re-encode the streams:
// Analyze input
auto info = primo::make_ref(Library::createMediaInfo());
info->inputs()->at(0)->setFile(primo::ustring("input.mp4"));
if (!info->open()) {
return false;
}
// Create input socket from MediaInfo
auto inputSocket = primo::make_ref(Library::createMediaSocket(info.get()));
// Create output socket with different encoding parameters
auto outputSocket = primo::make_ref(Library::createMediaSocket("mp4.h264.aac"));
outputSocket->setFile(primo::ustring("output.mp4"));
// Optionally customize encoding parameters
for (int i = 0; i < outputSocket->pins()->count(); i++) {
MediaPin* pin = outputSocket->pins()->at(i);
if (pin->streamInfo()->mediaType() == MediaType::Video) {
VideoStreamInfo* vsi = static_cast<VideoStreamInfo*>(pin->streamInfo());
vsi->setBitrate(2000000); // 2 Mbps
vsi->setFrameRate(30.0);
}
else if (pin->streamInfo()->mediaType() == MediaType::Audio) {
AudioStreamInfo* asi = static_cast<AudioStreamInfo*>(pin->streamInfo());
asi->setBitrate(128000); // 128 kbps
}
}
// Setup and run transcoder
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (transcoder->open()) {
transcoder->run();
transcoder->close();
}Decode a stream of H.264 Access Units (AUs):
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->setAllowDemoMode(true);
bool decoderInitialized = false;
int32_t index = 0;
for (int i = 0; ; i++) {
char auFile[PATH_MAX];
snprintf(auFile, PATH_MAX, "%s/au_%04d.h264", inputDir.c_str(), i);
if (!decoderInitialized) {
// Use MediaInfo on first AU to get stream properties
auto info = primo::make_ref(Library::createMediaInfo());
info->inputs()->at(0)->setFile(primo::ustring(auFile));
if (!info->open()) {
return false;
}
// Create input socket without file (will push data)
auto inSocket = primo::make_ref(Library::createMediaSocket(info.get()));
inSocket->setFile(NULL);
inSocket->setStream(NULL);
// Create output socket for YUV
auto outSocket = primo::make_ref(Library::createMediaSocket());
outSocket->setFile(primo::ustring("output.yuv"));
outSocket->setStreamType(StreamType::UncompressedVideo);
auto pin = primo::make_ref(Library::createMediaPin());
auto vsi = primo::make_ref(Library::createVideoStreamInfo());
vsi->setStreamType(StreamType::UncompressedVideo);
vsi->setColorFormat(ColorFormat::YUV420);
pin->setStreamInfo(vsi.get());
outSocket->pins()->add(pin.get());
transcoder->inputs()->add(inSocket.get());
transcoder->outputs()->add(outSocket.get());
if (!transcoder->open()) {
return false;
}
decoderInitialized = true;
}
// Read AU data
std::vector<uint8_t> auData = readFileBytes(auFile);
if (auData.size() <= 0)
break;
// Push AU to decoder
auto sample = primo::make_ref(Library::createMediaSample());
auto buffer = primo::make_ref(Library::createMediaBuffer());
buffer->attach(auData.data(), auData.size(), true);
sample->setBuffer(buffer.get());
if (!transcoder->push(index, sample.get())) {
printError("Transcoder push", transcoder->error());
return false;
}
}
transcoder->flush();
transcoder->close();Always check return values and handle errors properly:
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
if (!transcoder->open()) {
const primo::error::ErrorInfo* e = transcoder->error();
if (e->facility() == primo::error::ErrorFacility::Success) {
std::cout << "Success" << std::endl;
}
else {
if (e->message()) {
std::cout << "Error: " << primo::ustring(e->message()) << std::endl;
}
std::cout << "Facility: " << e->facility()
<< ", Code: " << e->code();
if (e->hint()) {
std::cout << ", Hint: " << primo::ustring(e->hint());
}
std::cout << std::endl;
}
return false;
}
// For pull mode, check for end of stream
while (transcoder->pull(outputIndex, sample.get())) {
// Process sample
}
const primo::error::ErrorInfo* error = transcoder->error();
if (error->facility() == primo::error::ErrorFacility::Codec &&
error->code() == primo::codecs::CodecError::EOS) {
// Successfully reached end of stream - this is normal
}
else {
// Actual error occurred
printError("Transcoder pull", error);
}AVBlocks uses reference counting. Use primo::ref<> or primo::make_ref() smart pointers for automatic memory management:
// Using primo::ref with explicit constructor
primo::ref<Transcoder> transcoder(Library::createTranscoder());
// Automatically released when ref goes out of scope
// Using primo::make_ref (C++11 style)
auto socket = primo::make_ref(Library::createMediaSocket());
// Raw pointers are used when object ownership is managed elsewhere
MediaPin* pin = socket->pins()->at(0);
StreamInfo* si = pin->streamInfo();
// Don't delete raw pointers obtained from AVBlocks API
// They are managed by their container objects- Link against
libAVBlocks.dylib - Use
primo::ustringfor file paths to handle Unicode correctly
- Link against
libAVBlocks64.so - Ensure library path is in
LD_LIBRARY_PATHor userpath - Use
primo::ustringfor file paths to handle Unicode correctly
- Link against
AVBlocks64.lib(64-bit) AVBlocks64.dllDLL must be in PATH or application directory- Use
/MTor/MTdruntime library option
Complete working examples are available in the samples directory.
Getting Started
simple_converter— Transcode a media file using aTranscoderwith hardcoded input and output file paths.
Media Info
info_metadata_file— Extract metadata information from a media fileinfo_stream_file— Extract the audio/video stream information from a media file
Decoding Audio
dec_aac_adts_file— Decode AAC file in ADTS format and save output to WAV filedec_aac_adts_pull— Decode AAC file in ADTS format usingTranscoder::pulland save output to WAV filedec_g711_alaw_file— Decode G.711 A-law WAV file to PCM WAV filedec_g711_ulaw_file— Decode G.711 μ-law WAV file to PCM WAV filedec_mp3_file— Decode MP3 file and save output to WAV filedec_opus_file— Decode Opus OGG file and save output to WAV filedec_vorbis_file— Decode Vorbis OGG file and save output to WAV file
Decoding Video
dec_avc_au— Decode a H.264 stream using sequence of files to simulate a stream of H.264 Access Unitsdec_avc_file— Decode AVC/H.264 Annex B compressed file to YUV uncompressed filedec_hevc_au— Decode an H.265 stream using sequence of files to simulate a stream of H.265 Access Unitsdec_hevc_file— Decode an HEVC/H.265 Annex B compressed file to a raw uncompressed YUV video filedec_vp8_file— Decode VP8 video in IVF container to YUV uncompressed filedec_vp9_file— Decode VP9 video in IVF container to YUV uncompressed file
Encoding Audio
enc_aac_adts_file— Encode WAV file to AAC file in ADTS formatenc_aac_adts_pull— Encode WAV file to AAC file in ADTS format usingTranscoder::pullenc_aac_adts_push— Encode WAV file to AAC file in ADTS format usingTranscoder::pushenc_g711_alaw_file— Encode WAV file to G.711 A-law WAV fileenc_g711_ulaw_file— Encode WAV file to G.711 μ-law WAV fileenc_mp3_file— Encode WAV file to MP3 fileenc_mp3_pull— Encode WAV file to MP3 file usingTranscoder::pullenc_mp3_push— Encode WAV file to MP3 file usingTranscoder::pushenc_opus_file— Encode WAV file to Opus OGG fileenc_vorbis_file— Encode WAV file to Vorbis OGG file
Encoding Video
enc_avc_file— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::runenc_avc_pull— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::pullenc_hevc_file— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::runenc_hevc_pull— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::pullenc_preset_file— Convert a raw YUV video file to a compressed video file using an AVBlocks presetenc_vp8_file— Encode raw YUV video file to VP8 video in IVF container usingTranscoder::runenc_vp9_file— Encode raw YUV video file to VP9 video in IVF container usingTranscoder::run
Muxing / Demuxing
demux_mp4_file— Extract the first audio and video elementary stream from an MP4 container into separate MP4 filesdemux_webm_file— Extract the first audio and video elementary stream from a WebM container into separate WebM filesdump_avc_au— Split an H.264 (AVC) elementary stream to access units (AU), writing each to a separate filedump_hevc_au— Split an H.265 (HEVC) elementary stream into access units (AU), writing each to a separate filemux_mp4_file— Multiplex two single-stream MP4 files (AAC audio + H.264 video) into an MP4 containermux_webm_file— Multiplex two single-stream WebM files (Vorbis audio + VP8 video) into a WebM container
Advanced
re-encode— Take an MP4 input and re-encode audio and video streams back into MP4 outputslideshow— Create a video clip from a sequence of images
Audio Processing
audio_upsample— Upsample audio from 44.1 KHz to 48 KHz
Video Processing
video_framerate— Change the frame rate of a video from 24 fps to 30 fpsvideo_pad— Add black border padding around a videovideo_crop— Crop a video by removing pixels from the edgesvideo_upscale— Upscale a video to Full HD (1920×1080) using bicubic interpolation
Getting Started
simple_converter— Transcode a media file using aTranscoderwith hardcoded input and output file paths.
Media Info
info_metadata_file— Extract metadata information from a media fileinfo_stream_file— Extract the audio/video stream information from a media file
Decoding Audio
dec_aac_adts_file— Decode AAC file in ADTS format and save output to WAV filedec_aac_adts_pull— Decode AAC file in ADTS format usingTranscoder::pulland save output to WAV filedec_g711_alaw_file— Decode G.711 A-law WAV file to PCM WAV filedec_g711_ulaw_file— Decode G.711 μ-law WAV file to PCM WAV filedec_mp3_file— Decode MP3 file and save output to WAV filedec_opus_file— Decode Opus OGG file and save output to WAV filedec_vorbis_file— Decode Vorbis OGG file and save output to WAV file
Decoding Video
dec_avc_au— Decode a H.264 stream using sequence of files to simulate a stream of H.264 Access Unitsdec_avc_file— Decode AVC/H.264 Annex B compressed file to YUV uncompressed filedec_hevc_au— Decode an H.265 stream using sequence of files to simulate a stream of H.265 Access Unitsdec_hevc_file— Decode an HEVC/H.265 Annex B compressed file to a raw uncompressed YUV video filedec_vp8_file— Decode VP8 video in IVF container to YUV uncompressed filedec_vp9_file— Decode VP9 video in IVF container to YUV uncompressed file
Encoding Audio
enc_aac_adts_file— Encode WAV file to AAC file in ADTS formatenc_aac_adts_pull— Encode WAV file to AAC file in ADTS format usingTranscoder::pullenc_aac_adts_push— Encode WAV file to AAC file in ADTS format usingTranscoder::pushenc_g711_alaw_file— Encode WAV file to G.711 A-law WAV fileenc_g711_ulaw_file— Encode WAV file to G.711 μ-law WAV fileenc_mp3_file— Encode WAV file to MP3 fileenc_mp3_pull— Encode WAV file to MP3 file usingTranscoder::pullenc_mp3_push— Encode WAV file to MP3 file usingTranscoder::pushenc_opus_file— Encode WAV file to Opus OGG fileenc_vorbis_file— Encode WAV file to Vorbis OGG file
Encoding Video
enc_avc_file— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::runenc_avc_pull— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::pullenc_hevc_file— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::runenc_hevc_pull— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::pullenc_preset_file— Convert a raw YUV video file to a compressed video file using an AVBlocks presetenc_vp8_file— Encode raw YUV video file to VP8 video in IVF container usingTranscoder::runenc_vp9_file— Encode raw YUV video file to VP9 video in IVF container usingTranscoder::run
Muxing / Demuxing
demux_mp4_file— Extract the first audio and video elementary stream from an MP4 container into separate MP4 filesdemux_webm_file— Extract the first audio and video elementary stream from a WebM container into separate WebM filesdump_avc_au— Split an H.264 (AVC) elementary stream to access units (AU), writing each to a separate filedump_hevc_au— Split an H.265 (HEVC) elementary stream into access units (AU), writing each to a separate filemux_mp4_file— Multiplex two single-stream MP4 files (AAC audio + H.264 video) into an MP4 containermux_webm_file— Multiplex two single-stream WebM files (Vorbis audio + VP8 video) into a WebM container
Advanced
re-encode— Take an MP4 input and re-encode audio and video streams back into MP4 outputslideshow— Create a video clip from a sequence of images
Audio Processing
audio_upsample— Upsample audio from 44.1 KHz to 48 KHz
Video Processing
video_framerate— Change the frame rate of a video from 24 fps to 30 fpsvideo_pad— Add black border padding around a videovideo_crop— Crop a video by removing pixels from the edgesvideo_upscale— Upscale a video to Full HD (1920×1080) using bicubic interpolation
Getting Started
simple_converter— Transcode a media file using aTranscoderwith hardcoded input and output file paths.
Media Info
info_metadata_file— Extract metadata information from a media fileinfo_stream_file— Extract the audio/video stream information from a media file
Decoding Audio
dec_aac_adts_file— Decode AAC file in ADTS format and save output to WAV filedec_aac_adts_pull— Decode AAC file in ADTS format usingTranscoder::pulland save output to WAV filedec_g711_alaw_file— Decode G.711 A-law WAV file to PCM WAV filedec_g711_ulaw_file— Decode G.711 μ-law WAV file to PCM WAV filedec_mp3_file— Decode MP3 file and save output to WAV filedec_opus_file— Decode Opus OGG file and save output to WAV filedec_vorbis_file— Decode Vorbis OGG file and save output to WAV file
Decoding Video
dec_avc_au— Decode a H.264 stream using sequence of files to simulate a stream of H.264 Access Unitsdec_avc_file— Decode AVC/H.264 Annex B compressed file to YUV uncompressed filedec_hevc_au— Decode an H.265 stream using sequence of files to simulate a stream of H.265 Access Unitsdec_hevc_file— Decode an HEVC/H.265 Annex B compressed file to a raw uncompressed YUV video filedec_vp8_file— Decode VP8 video in IVF container to YUV uncompressed filedec_vp9_file— Decode VP9 video in IVF container to YUV uncompressed file
Encoding Audio
enc_aac_adts_file— Encode WAV file to AAC file in ADTS formatenc_aac_adts_pull— Encode WAV file to AAC file in ADTS format usingTranscoder::pullenc_aac_adts_push— Encode WAV file to AAC file in ADTS format usingTranscoder::pushenc_g711_alaw_file— Encode WAV file to G.711 A-law WAV fileenc_g711_ulaw_file— Encode WAV file to G.711 μ-law WAV fileenc_mp3_file— Encode WAV file to MP3 fileenc_mp3_pull— Encode WAV file to MP3 file usingTranscoder::pullenc_mp3_push— Encode WAV file to MP3 file usingTranscoder::pushenc_opus_file— Encode WAV file to Opus OGG fileenc_vorbis_file— Encode WAV file to Vorbis OGG file
Encoding Video
enc_avc_file— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::runenc_avc_pull— Encode raw YUV video file to AVC/H.264 Annex B video file usingTranscoder::pullenc_hevc_file— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::runenc_hevc_pull— Encode raw YUV video file to HEVC/H.265 Annex B video file usingTranscoder::pullenc_preset_file— Convert a raw YUV video file to a compressed video file using an AVBlocks presetenc_vp8_file— Encode raw YUV video file to VP8 video in IVF container usingTranscoder::runenc_vp9_file— Encode raw YUV video file to VP9 video in IVF container usingTranscoder::run
Muxing / Demuxing
demux_mp4_file— Extract the first audio and video elementary stream from an MP4 container into separate MP4 filesdemux_webm_file— Extract the first audio and video elementary stream from a WebM container into separate WebM filesdump_avc_au— Split an H.264 (AVC) elementary stream to access units (AU), writing each to a separate filedump_hevc_au— Split an H.265 (HEVC) elementary stream into access units (AU), writing each to a separate filemux_mp4_file— Multiplex two single-stream MP4 files (AAC audio + H.264 video) into an MP4 containermux_webm_file— Multiplex two single-stream WebM files (Vorbis audio + VP8 video) into a WebM container
Advanced
re-encode— Take an MP4 input and re-encode audio and video streams back into MP4 outputslideshow— Create a video clip from a sequence of images
Audio Processing
audio_upsample— Upsample audio from 44.1 KHz to 48 KHz
Video Processing
video_framerate— Change the frame rate of a video from 24 fps to 30 fpsvideo_pad— Add black border padding around a videovideo_crop— Crop a video by removing pixels from the edgesvideo_upscale— Upscale a video to Full HD (1920×1080) using bicubic interpolation
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