HEVC / H.265 Annex B Encoder (Run)¶
This article explains how you can use {transcoder-run-net} to encode a raw YUV video file to HEVC / H.265 Annex B elementary stream format.
The code snippets in this article are from the enc_hevc_file .NET sample.
Source Video¶
The sample uses foreman_qcif.yuv from the AVBlocks Assets repository. After downloading and unzipping the assets, the file is in the vid subdirectory.
Code¶
Initialize AVBlocks¶
Initialize the library before using AVBlocks and shut it down when encoding is complete.
static int Main(string[] args)
{
var opt = new Options();
if (!opt.Prepare(args))
return opt.Error ? (int)ExitCodes.OptionsError : (int)ExitCodes.Success;
Library.Initialize();
bool encHevcFileResult = Encode(opt);
Library.Shutdown();
return encHevcFileResult ? (int)ExitCodes.Success : (int)ExitCodes.EncodingError;
}
Configure Input Socket¶
The input socket describes the raw YUV file. Its dimensions, frame rate, and color format must match the source file.
static MediaSocket CreateInputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.StreamType = StreamType.UncompressedVideo;
socket.File = opt.InputFile;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
VideoStreamInfo vsi = new VideoStreamInfo();
pin.StreamInfo = vsi;
vsi.StreamType = StreamType.UncompressedVideo;
vsi.ScanType = ScanType.Progressive;
vsi.FrameWidth = opt.Width;
vsi.FrameHeight = opt.Height;
vsi.ColorFormat = opt.Color.Id;
vsi.FrameRate = opt.Fps;
return socket;
}
Configure Output Socket¶
Set the output stream type to H265 and the subtype to HevcAnnexB to produce an elementary HEVC stream.
static MediaSocket CreateOutputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.File = opt.OutputFile;
socket.StreamType = StreamType.H265;
socket.StreamSubType = StreamSubType.HevcAnnexB;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
VideoStreamInfo vsi = new VideoStreamInfo();
pin.StreamInfo = vsi;
vsi.StreamType = StreamType.H265;
vsi.StreamSubType = StreamSubType.HevcAnnexB;
return socket;
}
Configure and Run Transcoder¶
Create the sockets, enable demo mode, add the sockets to a transcoder, and run it. The sample removes an existing output because the transcoder intentionally fails when the output file already exists.
static bool Encode(Options opt)
{
DeleteFile(opt.OutputFile);
MediaSocket inSocket = CreateInputSocket(opt);
MediaSocket outSocket = CreateOutputSocket(opt);
// create Transcoder
using (Transcoder transcoder = new Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
bool res = transcoder.Open();
PrintError("Transcoder open", transcoder.Error);
if (!res)
return false;
res = transcoder.Run();
PrintError("Transcoder run", transcoder.Error);
if (!res)
return false;
transcoder.Close();
PrintError("Transcoder close", transcoder.Error);
if (!res)
return false;
}
return true;
}
Complete Code¶
Here’s the complete working example that demonstrates HEVC/H.265 encoding using AVBlocks for .NET. This code combines all the previous snippets into a functional program.
using System;
using PrimoSoftware.AVBlocks;
namespace CliSample
{
class Program
{
static int Main(string[] args)
{
var opt = new Options();
if (!opt.Prepare(args))
return opt.Error ? (int)ExitCodes.OptionsError : (int)ExitCodes.Success;
Library.Initialize();
// Set license information. To run AVBlocks in demo mode, comment the next line out
// Library.SetLicense("<license-string>");
bool encHevcFileResult = Encode(opt);
Library.Shutdown();
return encHevcFileResult ? (int)ExitCodes.Success : (int)ExitCodes.EncodingError;
}
static bool Encode(Options opt)
{
DeleteFile(opt.OutputFile);
MediaSocket inSocket = CreateInputSocket(opt);
MediaSocket outSocket = CreateOutputSocket(opt);
// create Transcoder
using (Transcoder transcoder = new Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
bool res = transcoder.Open();
PrintError("Transcoder open", transcoder.Error);
if (!res)
return false;
res = transcoder.Run();
PrintError("Transcoder run", transcoder.Error);
if (!res)
return false;
transcoder.Close();
PrintError("Transcoder close", transcoder.Error);
if (!res)
return false;
}
return true;
}
static void DeleteFile(string filename)
{
try
{
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename);
}
catch { }
}
static MediaSocket CreateInputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.StreamType = StreamType.UncompressedVideo;
socket.File = opt.InputFile;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
VideoStreamInfo vsi = new VideoStreamInfo();
pin.StreamInfo = vsi;
vsi.StreamType = StreamType.UncompressedVideo;
vsi.ScanType = ScanType.Progressive;
vsi.FrameWidth = opt.Width;
vsi.FrameHeight = opt.Height;
vsi.ColorFormat = opt.Color.Id;
vsi.FrameRate = opt.Fps;
return socket;
}
static MediaSocket CreateOutputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.File = opt.OutputFile;
socket.StreamType = StreamType.H265;
socket.StreamSubType = StreamSubType.HevcAnnexB;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
VideoStreamInfo vsi = new VideoStreamInfo();
pin.StreamInfo = vsi;
vsi.StreamType = StreamType.H265;
vsi.StreamSubType = StreamSubType.HevcAnnexB;
return socket;
}
static void PrintError(string action, ErrorInfo e)
{
if (action != null)
{
Console.Write("{0}: ", action);
}
if (ErrorFacility.Success == e.Facility)
{
Console.WriteLine("Success");
return;
}
else
{
Console.WriteLine("{0}, facility:{1} code:{2} hint:{3}", e.Message ?? "", e.Facility, e.Code, e.Hint ?? "");
}
}
enum ExitCodes : int
{
Success = 0,
OptionsError = 1,
EncodingError = 2,
}
}
}
How to Run¶
See the enc_hevc_file .NET sample for details.
Command Line¶
enc_hevc_file --frame <width>x<height> --rate <fps> --color <color> --input <file.yuv> --output <file.h265> [--colors]
Examples¶
List options:
./bin/net10.0/enc_hevc_file --help
Encode a raw YUV video from ./assets/vid/foreman_qcif.yuv to a H.265 video in ./output/enc_hevc_file/foreman_qcif.h265:
# Linux and macOS
mkdir -p ./output/enc_hevc_file
./bin/net10.0/enc_hevc_file \
--input ./assets/vid/foreman_qcif.yuv \
--output ./output/enc_hevc_file/foreman_qcif.h265 \
--frame 176x144 \
--rate 30 \
--color yuv420
# Windows
mkdir -Force -Path ./output/enc_hevc_file
./bin/net10.0/enc_hevc_file `
--input ./assets/vid/foreman_qcif.yuv `
--output ./output/enc_hevc_file/foreman_qcif.h265 `
--frame 176x144 `
--rate 30 `
--color yuv420