LFile Reference Manual & Qt Playout Guide
The LFile class is the core file playout and decoding engine of the now2sdk framework, derived from the base LObject class. It is designed to read, decode, filter, format, and stream local media files (MP4, MKV, MOV, AVI, MXF, TS, etc.) or image sequences frame-by-frame (AVFrame*) synchronously to registered sinks such as LPreview, LMixer, LRecorder, or LOutput.
Under the hood, LFile is built on a highly optimized, multi-threaded FFmpeg pipeline (libavformat, libavcodec, libswresample, libavfilter).
1. Architectural Concept & Core Pipelines
graph TD
A[Local Media File / Image Sequence] --> B[FFmpeg Demuxer - libavformat]
B -->|Video Packets| C[Video Decoder - CPU / GPU Hardware]
B -->|Audio Packets| D[Audio Decoder - libavcodec]
C --> E{Bypass Mode?}
E -->|Yes: gpu=true| H[Direct Frame Queue]
E -->|No: gpu=false| F[FFmpeg Video Filter Graph]
F -->|Deinterlacing: bwdif| G[Dynamic Scaling / Padding / Frame Rate conversion]
G -->|Custom Filters: LFilter| H
D --> I[FFmpeg Audio Filter Graph]
I -->|Audio Delay: adelay| J[Resampler / Peak Calculator]
J -->|Custom Filters: LFilter| K[Audio Frame Queue]
H --> L[distributeVideoFrame]
K --> M[distributeAudioFrame]
L --> N[Sinks: LPreview / LMixer / LOutput / LRecorder]
M --> N
Key Subsystems:
- Frame-Accurate Clock Synchronization: Playback timing is managed using a high-precision
steady_clock. Frames are scheduled and delayed dynamically based on their presentation timestamp (PTS) and the activeplaybackRate. - Direct GPU Bypass Path: Activated when
gpuis set totrueand no filters or output formatting properties are specified. This mode completely bypasses the CPU filter graph (scaling, padding, format conversion) for zero-copy efficiency. - FFmpeg Video Filter Graph Builder: Dynamically builds filter chains at runtime to perform aspect-ratio conversions (
letter-box,crop, orstretch), deinterlacing (bwdif), custom color spaces (ARGB32, NV12, UYVY, etc.), frame-rate adjustments, and developer-defined custom effects. - Image Sequence Reader: Automatically detects image sequence directories if the file path contains wildcard patterns (e.g.
/path/to/sequence_%04d.png), utilizing the FFmpegimage2format driver. - Multi-Track Audio Demuxing: Supports switching audio tracks inside container files dynamically at runtime, as well as applying individual channel delay filters (
adelay) and output format normalization.
2. API Reference & Key Methods
📌 Playback Control Methods
void fileNameSet(const std::string& filePath);
Sets the path of the media file or image sequence. If the file is currently playing, it automatically stops the playback before applying the new path.
bool play();
Opens the file, initializes FFmpeg decoders, starts the internal decoding thread, and begins distributing audio/video frames. Returns true if successful.
void pause(double ms = 0);
Pauses playback. If ms is greater than 0, it configures an automatic timer to resume playback after the specified duration in milliseconds.
void resume();
Resumes paused playback.
void stop();
Stops the decoding thread, flushes all registered sinks, closes the file, and releases all decoder contexts and FFmpeg resources.
void statusGet(int& status) override;
Retrieves the player's active state. Sets status to 1 if running/playing, and 0 if stopped.
bool isPaused() const;
Checks if the player is currently paused.
bool isRunning() const;
Checks if the player's decoding thread is active.
bool isEOF() const;
Checks if the player has reached the End of File (EOF) or the specified Out point.
📌 Precision Navigation & Seek Methods
void setPos(double ms);
void PosSet(double ms); // Backward compatibility wrapper
Seeks immediately to the specified position in milliseconds. The player is automatically resumed if paused to decode the target keyframe.
double getPos();
double PosGet(); // Backward compatibility wrapper
Returns the current playhead position in milliseconds.
void setPosTC(const std::string& tc);
Seeks to a target position using a standard Timecode string ("HH:MM:SS:FF"). The position is calculated relative to the file's start timecode.
std::string getPosTC();
Returns the current playhead position formatted as a Timecode string ("HH:MM:SS:FF").
void RateSet(double rate);
Sets the playback speed rate.
1.0: Normal speed.2.0: Fast forward (2x).0.5: Slow motion (0.5x).
double RateGet();
Returns the active playback rate.
void InOutSet(double inMs, double outMs);
Restricts playback bounds. Playback will seek to inMs on start/loop and stop or loop immediately when hitting outMs.
void InOutGet(double& inMs, double& outMs, double& durationMs);
Retrieves the defined In/Out points as well as the total media duration in milliseconds.
std::string getInTC();
std::string getOutTC();
Returns the In and Out points formatted as standard Timecode strings ("HH:MM:SS:FF").
📌 Properties & Format Configurations
void setProps(const std::string& key, const std::string& value);
Sets custom properties using a key-value structure. Details of available keys are documented in Section 3.
void setAudioDelay(int ms);
void setVideoDelay(int ms);
Applies static latency offset adjustments to the audio or video output streams, enabling synchronization troubleshooting.
void setVideoFilter(LFilter* filter);
void setAudioFilter(LFilter* filter);
Binds a custom video or audio LFilter graph to be dynamically parsed and integrated into the stream processing chain.
void setVideoFormat(const videoFormatProps& props);
void getVideoFormat(videoFormatProps& props);
Configures target format normalization rules for the output video frames (e.g. forcing frame resizing or colorspace conversions).
void setAudioFormat(const audioFormatProps& props);
void getAudioFormat(audioFormatProps& props);
Configures target normalization formatting rules for audio frames (sample rate, channels, bits per sample).
📌 Metrics & Info Getters
double getDurationMs();
Returns the total duration of the media file in milliseconds.
double getFPS() override;
Returns the frame rate of the output stream. If a target video format is defined, it returns the target FPS, otherwise falls back to the source file's original FPS.
std::string getTimeCode() override;
Returns the current Timecode. Overrides the base LObject behavior by calling getPosTC().
int getWidth();
int getHeight();
Returns the original width and height of the video track in pixels.
void getAudioPeak(float& left, float& right);
Retrieves the maximum audio peak amplitude (normalized range 0.0 to 1.0) processed during the last frame decode cycle.
void resetAudioPeak();
Resets the left and right channel audio peak registers to 0.0.
3. Properties & Configuration Options
All options listed below are configured at runtime via the setProps(const std::string& key, const std::string& value) interface:
| Key | Value Type | Default Value | Description |
|---|---|---|---|
loop |
bool |
"false" |
Loops playback back to inPointMs (or 0) upon hitting EOF or outPointMs. |
audio_gain |
int |
"100" |
Master audio volume coefficient percentage (0 to 100). |
audio_track |
int |
"0" |
Index of the target audio stream to decode inside multi-lingual files. |
eof_hold |
bool |
"true" |
When EOF is reached without loop enabled, freezes and keeps transmitting the last decoded video frame instead of stopping. |
deinterlace |
bool |
"false" |
Dynamically enables/disables the bwdif deinterlacing filter. |
gpu |
bool |
"false" |
Direct bypass mode. Skips scaling/padding pipeline to transmit raw video frames directly to sinks. |
scaling_quality |
int |
"0" |
Configures the SwScale scaling algorithms:0: SWS_BICUBIC (Auto Quality)1: SWS_POINT (Nearest Neighbor)2: SWS_BILINEAR3: SWS_BICUBIC4: SWS_LANCZOS |
scale_type |
string |
"letter-box" |
Layout aspect-ratio fitting style:"letter-box": Fit with black bars."crop": Zoom and crop."stretch": Stretch/squeeze. |
timecodeSource |
int |
"1" |
Selects Timecode anchor generator:0: Current System Clock.1: Source File Metadata Header. |
rate / speed |
double |
"1.0" |
Adjusts the playback speed rate. |
log |
bool |
"false" |
Enables or disables event & crash logging for the player instance. |
log.path |
string |
"./logs/" |
Target directory for log files. Supports tilde expansion (~/.config/...) and auto-creates folders if missing. Defaults to ./logs/ if omitted. |
log.name / setname |
string |
"LFile" |
Module or channel tag printed in log entries (e.g. PLAYER_1). |
log.file |
string |
"sdk_app" |
Base name of the log file (extension .log is added automatically). Rotates automatically every 24 hours (appending _YYYY-MM-DD.log). Multiple modules sharing the same log.file name write safely to the same daily file. |
4. Qt Playout Integration Example
This example demonstrates how to integrate LFile in a Qt window. It builds a media playlist player with progress indicators, playback control buttons (Play, Pause, Stop, Seek), real-time volume calculations, and color/audio processing filters.
mainwindow.h
#pragma once
#include <QMainWindow>
#include <QTimer>
#include <QStringList>
#include "LFile.h"
#include "LPreview.h"
#include "LFilter.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void onPlayClicked();
void onPauseClicked();
void onStopClicked();
void onSeekSliderMoved(int position);
void updateUI();
private:
Ui::MainWindow* ui;
LFile* m_lFile;
LPreview* m_lPreview;
LFilter* m_videoColorFilter;
LFilter* m_audioDelayFilter;
QTimer* m_uiTimer;
};
mainwindow.cpp
#include "`mainwindow.h`"
#include "./ui_mainwindow.h"
#include "LFormat.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow),
m_lFile(new LFile()),
m_lPreview(new LPreview()),
m_uiTimer(new QTimer(this))
{
ui->setupUi(this);
// 1. Initial configuration for Playout Engine
m_lFile->fileNameSet("/home/alsaberk/Videos/commercial_break.mp4");
m_lFile->setProps("loop", "true");
m_lFile->setProps("eof_hold", "true");
m_lFile->setProps("scale_type", "letter-box");
m_lFile->setProps("scaling_quality", "4"); // Use high-quality Lanczos scaling
// 2. Configure Normalization Targets
videoFormatProps videoTarget;
videoTarget.setVideoFormat = vF::HD1080_50p; // Force 1920x1080 at 50fps
videoTarget.colorSpace = cS::fcc_UYVY; // Target output colorspace
m_lFile->setVideoFormat(videoTarget);
audioFormatProps audioTarget;
audioTarget.setAudioFormat = aF::_16B_48K_2CH; // Normalize to 16-bit PCM 48kHz Stereo
m_lFile->setAudioFormat(audioTarget);
// 3. Optional: Dynamic Video & Audio Processing Filters
m_videoColorFilter = new LFilter(LFilter::Video);
// Apply real-time brightness, contrast, and saturation adjustments
m_videoColorFilter->setProps("eq", "brightness=1.05:contrast=1.1:saturation=1.2");
m_lFile->setVideoFilter(m_videoColorFilter);
m_audioDelayFilter = new LFilter(LFilter::Audio);
// Inject a 150ms audio offset to resolve sync mismatches
m_audioDelayFilter->setProps("adelay", "delays=150ms|150ms");
m_lFile->setAudioFilter(m_audioDelayFilter);
// 4. Connect Playout Engine to preview sink widget
m_lPreview->setProps("ui_framework", "qt");
m_lPreview->setProps("audio_meter", "true");
m_lPreview->setProps("timecode.preview", "true");
// Bind to the preview widget inside the Qt UI structure
m_lPreview->previewEnable(ui->playerPreviewWidget, true, true);
m_lPreview->previewObject(m_lFile);
// 5. Connect UI Triggers
connect(ui->playBtn, &QPushButton::clicked, this, &MainWindow::onPlayClicked);
connect(ui->pauseBtn, &QPushButton::clicked, this, &MainWindow::onPauseClicked);
connect(ui->stopBtn, &QPushButton::clicked, this, &MainWindow::onStopClicked);
connect(ui->progressSlider, &QSlider::sliderMoved, this, &MainWindow::onSeekSliderMoved);
// 6. Start UI refresh loop (50ms interval)
connect(m_uiTimer, &QTimer::timeout, this, &MainWindow::updateUI);
m_uiTimer->start(50);
}
MainWindow::~MainWindow() {
m_lFile->stop();
delete m_lPreview;
delete m_videoColorFilter;
delete m_audioDelayFilter;
delete m_lFile;
delete ui;
}
void MainWindow::onPlayClicked() {
m_lFile->play();
}
void MainWindow::onPauseClicked() {
m_lFile->pause();
}
void MainWindow::onStopClicked() {
m_lFile->stop();
}
void MainWindow::onSeekSliderMoved(int position) {
// Seek instantly to specified millisecond position
m_lFile->setPos(static_cast<double>(position));
}
void MainWindow::updateUI() {
double currentMs = m_lFile->getPos();
double durationMs = m_lFile->getDurationMs();
// Update Slider limits and values
ui->progressSlider->setMaximum(static_cast<int>(durationMs));
ui->progressSlider->setValue(static_cast<int>(currentMs));
// Update Timecode metrics
ui->timecodeLabel->setText(QString::fromStdString(m_lFile->getPosTC()));
// Update VU Levels
float peakL = 0.0f;
float peakR = 0.0f;
m_lFile->getAudioPeak(peakL, peakR);
ui->vuMeterLeft->setValue(static_cast<int>(peakL * 100));
ui->vuMeterRight->setValue(static_cast<int>(peakR * 100));
}
5. .NET Playout Integration Example (WinForms / VB.NET / C#)
This example demonstrates how to integrate LFile with C# or VB.NET using the managed Now2Media.SDK.dll wrapper inside a standard Windows Forms application.
VB.NET Example (Form1.vb)
Imports Now2Media.SDK
Public Class Form1
Private _file As LFile
Private _preview As LPreview
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' 1. Instantiate Core SDK Objects
_file = New LFile()
_preview = New LPreview()
' 2. Enable Video Preview Control on WinForms Panel Handle (HWND)
_preview.previewEnable(VideoPanel.Handle, True, True)
' 3. Route File Stream to Video Preview Control
_preview.previewObject(_file)
' 4. Configure Overlay Display Options
_preview.setProps("audio_meter", "true")
_preview.setProps("border", "true")
_preview.setProps("status", "program") ' Red tally border outline
_preview.setProps("name", "WIN32 GPU PLAYOUT")
' 5. Select Media File and Start Playback
_file.fileNameSet("C:\Media\video.mp4")
_file.play()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
' Clean up unmanaged wrappers on close
_file.stop()
_preview.Dispose()
End Sub
End Class
C# Example (Form1.cs)
using System;
using System.Windows.Forms;
using Now2Media.SDK;
namespace Now2SDKTest
{
public partial class Form1 : Form
{
private LFile _file;
private LPreview _preview;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// 1. Instantiate Core SDK Objects
_file = new LFile();
_preview = new LPreview();
// 2. Enable Video Preview Control on Panel Handle (HWND)
_preview.previewEnable(VideoPanel.Handle, true, true);
// 3. Route File Stream to Video Preview Control
_preview.previewObject(_file);
// 4. Configure Overlay Display Options
_preview.setProps("audio_meter", "true");
_preview.setProps("border", "true");
_preview.setProps("status", "program");
_preview.setProps("name", "WIN32 GPU PLAYOUT");
// 5. Select Media File and Start Playback
_file.fileNameSet(@"C:\Media\video.mp4");
_file.play();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_file.stop();
_preview.Dispose();
}
}
}