Over the years, I've written quite a bit of timecode-related code across various projects. This library represents my effort to gather all of that knowledge and code into a single, cohesive place. If you work with video timecode, this library aims to make your life easier.
Standards Compliance: Implements SMPTE 12M-1-2008 television timecode handling and Linear Time Code (LTC). See the SMPTE compliance doc for details.
This library provides comprehensive C (with optional C++) interfaces for working with video timecode:
- Timecode Math: Add, subtract, increment, decrement timecodes with proper handling of drop-frame and non-drop-frame formats
- Timecode Conversion: Convert between timecode, frame counts, and wall clock time
- Timecode Packing: Pack and unpack timecode to/from the binary formats used in LTC, SDI, and other video systems
- LTC Support: Read and write Linear Timecode (audio-encoded timecode)
- Format Support: Handle various video formats (23.98, 24, 25, 29.97DF/NDF, 30DF/NDF fps)
The optional C++ interface provides object-oriented wrappers around the C API and can be enabled via CMake build options.
- CMake 3.15 or newer
- C99-compatible compiler (GCC, Clang, MSVC)
- Standard math library
mkdir build && cd build
cmake ..
make
make testVTC_BUILD_SHARED- Build shared library (default: ON)VTC_BUILD_STATIC- Build static library (default: ON)VTC_BUILD_CPP- Build C++ interface (default: OFF)VTC_BUILD_TESTS- Build test suite (default: ON)VTC_BUILD_UTILS- Build utility programs (default: ON)
Example with custom options:
cmake -DVTC_BUILD_CPP=ON -DVTC_BUILD_TESTS=OFF ..make installThis installs:
- Headers to
/usr/local/include/vtc/ - Libraries to
/usr/local/lib/ - pkg-config file to
/usr/local/lib/pkgconfig/
Include the main header in your code:
#include <vtc/vtc.h>Link against the library:
gcc myapp.c -lvtc -lmOr use pkg-config:
gcc myapp.c $(pkg-config --cflags --libs vtc)#include <vtc/vtc.h>
#include <stdio.h>
int main(void) {
// Create a timecode
VtcTimecode tc;
vtc_timecode_init(&tc, &VTC_FORMAT_29_97_DF);
vtc_timecode_set(&tc, 1, 0, 0, 0); // 01:00:00:00
// Convert to string
char str[VTC_TIMECODE_STRING_MAX];
vtc_timecode_to_string(&tc, str, sizeof(str));
printf("Timecode: %s\n", str);
return 0;
}#include <vtc/vtc.h>
#include <stdio.h>
// Callback for decoded LTC frames
void on_ltc_decoded(const VtcTimecode *tc, int64_t sample_start,
int64_t sample_length, void *user_data) {
printf("Decoded LTC at sample %ld: %02d:%02d:%02d:%02d\n",
sample_start, tc->hour, tc->min, tc->sec, tc->frame);
}
int main(void) {
// Encode timecode to audio
VtcTimecode tc;
vtc_timecode_init(&tc, &VTC_FORMAT_24);
vtc_timecode_set(&tc, 1, 0, 0, 0);
int8_t audio_buffer[4000];
VtcLTCEncoder encoder;
VtcRational fps = {24, 1};
vtc_ltc_encoder_init(&encoder, 48000, fps, 0.5f);
size_t samples = vtc_ltc_audio_encode(&encoder, &tc,
audio_buffer, sizeof(audio_buffer));
printf("Encoded %zu audio samples\n", samples);
// Decode audio back to LTC
VtcLTCDecoder decoder;
vtc_ltc_decoder_init(&decoder, 48000, on_ltc_decoded, NULL);
vtc_ltc_decoder_decode(&decoder, audio_buffer, samples);
return 0;
}This library is actively being developed. The core timecode functionality is stable and tested, but additional features (like full LTC encoding/decoding) are still being implemented.
Currently implemented:
- [Done] Core timecode structures and validation
- [Done] Format definitions and utilities
- [Done] Timecode math operations
- [Done] Frame and time conversions
- [Done] String parsing and formatting
- [Done] LTC binary packing/unpacking (bits 0-79)
- [Done] LTC audio encoding (VtcLTC -> int8_t audio samples)
- [Done] LTC audio decoding (int8_t audio samples -> VtcLTC with callback)
- [Note] LTC audio round-trip needs debugging (encoder/decoder logic)
This project is licensed under the MIT License - see the LICENSE file for details.
This is primarily a personal collection of code, but if you find bugs or have suggestions, feel free to open an issue or submit a pull request.
Howard Logic https://howardlogic.com