Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
864da46
add MP4GetMovieIndTrackNALUnitLength API
podborski Apr 23, 2025
f9d7a6b
Merge branch 'config_records' into t35
podborski Apr 23, 2025
f6e0ab1
ISOAddT35GroupDescription and other things
podborski Apr 28, 2025
7289fca
when defragmenting an empty stts make sure to add the first entry
podborski Jul 8, 2025
48ff054
just go for it :)
podborski Jul 8, 2025
aeb5405
add a simple test for T35 mebx
podborski Sep 9, 2025
fa9bb7f
initial implementation of t35_tool
podborski Sep 12, 2025
20e426a
add ISOBMFF colr box implementation
podborski Sep 12, 2025
0a47831
use cli11 lib
podborski Sep 12, 2025
0cfa797
demux mebx samples to binary blobs of data
podborski Sep 12, 2025
b21acf8
encapsulate into boxes when muxing, use trackreaders when deumxing
podborski Sep 15, 2025
a6d718c
this is not a bug, sorry for the noise
podborski Sep 15, 2025
f58de9a
API brushup, select mebx data based on key info
podborski Sep 16, 2025
cdcf1c6
dump NALUs from sample entry
podborski Sep 16, 2025
d7670da
add CLI option to set T.35 prefix
podborski Sep 16, 2025
3d8c6ab
initial implementatio of SEI injection
podborski Sep 16, 2025
3d2f68d
use rndr track reference type
podborski Sep 16, 2025
c25f3b3
Add inject and extract of SMPTE ST 2094-50 metadata from json file
Oct 2, 2025
5454552
Merge pull request #1 from img-standards/smpte_st_2094_50
podborski Oct 21, 2025
df88959
Fix gain max/span
Nov 6, 2025
4976c0c
put as text
podborski Nov 6, 2025
eae66de
search for correct mebx track, never give up :)
podborski Nov 15, 2025
754cbf0
Fix headroom offset and scaling (application version = 1111)
Nov 17, 2025
40ef7f2
Merge branch 't35_mebx' of https://github.pie.apple.com/img-standards…
Nov 17, 2025
075f394
write SEI T.35 header correctly
podborski Nov 17, 2025
2c07c9a
Update to use structure rather flat list and use latest version
Nov 21, 2025
a4f581f
Add classes for SMPTE 2094-50 -> Inject only working
Nov 21, 2025
ee1e039
Update decoding
Nov 22, 2025
e8724ee
Merge branch 'config_records' into t35
podborski Nov 27, 2025
6706e9b
Merge branch 'config_records' into t35
podborski Nov 27, 2025
199a23e
Pull and push data using simple function to make code simpler
Dec 1, 2025
131283c
Add dumping metadata items to json
Dec 1, 2025
f77697a
Add payload_data to metadataItems -> need to remove intermediate .bin…
Dec 22, 2025
0fdcf39
Update naming of component mix flag
Dec 22, 2025
42fa841
Merge pull request #2 from img-standards/ST2094_PCD_V2
podborski Jan 8, 2026
9e37f56
graceful handling of malformed JSONs
podborski Jan 13, 2026
022398b
add refactored files
podborski Jan 13, 2026
e60e8b2
Latest PC2 Update and cleaning some debug command
Jan 15, 2026
81a2895
Added verbose level amd cleaned up logging
Jan 15, 2026
e77814e
Remove intermediate binary data file
Jan 15, 2026
8cbef04
Auto-adjust metadata duration when exceeding video length
Jan 15, 2026
b1257bf
add T35 metadata track sample entry and box
podborski Jan 15, 2026
e01eaf9
Implement convenience API for easy track creation
podborski Jan 15, 2026
e50b00a
make sure trackreference type can be provided as arg
podborski Jan 15, 2026
4f427e1
implement dedicated T.35 track stuff
podborski Jan 15, 2026
e6cd833
me4c extractor + auto extractor
podborski Jan 15, 2026
b9b6625
make sure to use prefix in extraction mode. add tests
podborski Jan 15, 2026
2fa70db
make sure we can handle multiple keyboxes with same ns and value
podborski Jan 15, 2026
862f227
me4c seem to work now
podborski Jan 15, 2026
1d4d064
cache track reader
podborski Jan 15, 2026
dac5c82
add track caching to other 2 extractors
podborski Jan 15, 2026
b0e5b54
add sample groups
podborski Jan 15, 2026
0441103
reuse existing sample group description if found
podborski Jan 15, 2026
7c40e51
Add Readme.md
Jan 15, 2026
2cd8a71
Fix Printing metadata when no HATM
Jan 15, 2026
9338183
Add displaying of metadata when SMPTE at decode time
Jan 15, 2026
b8956b3
SEI extraction / cleanups
podborski Jan 19, 2026
77361c4
Merge branch 't35' into t35_tool
podborski Jan 19, 2026
84885a5
Add includes to SMPTE_ST2094_50.cpp
y-guyon Jan 28, 2026
dcb542d
Merge pull request #62 from y-guyon/patch-1
podborski Jan 28, 2026
cbedcbb
bugfix QTFF keys
podborski Feb 10, 2026
aa36f75
ST2094-50: fix quantization constant and refine logic for common flag…
Feb 10, 2026
b4a8f79
Merge branch 't35_tool' into t35_mebx
Feb 10, 2026
107349e
Merge pull request #4 from img-standards/t35_mebx
Feb 10, 2026
9f91e6f
remove mebx with it35 namespace as it was not agreed at MPEG
podborski Feb 10, 2026
8577419
remove t35C as it was not agreed at MPEG
podborski Feb 10, 2026
ba10ce1
cleanup testdata for t35_tool
podborski Feb 10, 2026
aa38431
remove legacy code
podborski Feb 10, 2026
5c4c744
test scripts updates
podborski Feb 10, 2026
0188969
me4c bugfix
podborski Feb 10, 2026
a0f9457
clangformat
podborski Feb 10, 2026
f2a1183
ST2094-50 Remove extra byte when no headroom-adaptive tone mapping
Feb 16, 2026
b7da55c
Update SMPTE_ST2094_50.cpp
Feb 17, 2026
83a6e12
Merge branch 'master' of https://github.com/MPEGGroup/isobmff into t3…
podborski Feb 17, 2026
7a4564f
update clang format stuff
podborski Feb 17, 2026
8454624
windows build fix
podborski Feb 18, 2026
387cc66
fix tests
podborski Feb 18, 2026
c6aa9d7
try fixing clang format thing
podborski Feb 18, 2026
3137a7c
[ST2094-50] angle to slope metadata item update
Feb 18, 2026
760edb5
Merge branch 't35_tool' of https://github.com/MPEGGroup/isobmff into …
Feb 18, 2026
2f96263
[ST2095-50] common flag check fix
Feb 25, 2026
5aff53c
Dedicated-it35 Fix close media edits
Mar 2, 2026
9f176cb
[ST2094-50] Fix at decode scaling of component mix when not equal to 1.0
Mar 3, 2026
2a17c84
Fix it35 sample entry parsing and identifier extraction
podborski Mar 10, 2026
3997f3e
pring debug message of what we found vs what we requested
podborski Mar 10, 2026
45df3ed
Align extra closing curly brace in ST2094_50.cpp (#64)
y-guyon Mar 24, 2026
43b103f
Remove clang warnings (#66)
y-guyon Mar 24, 2026
feb9c39
Run clang-format on all IsoLib/t35_tool files (#67)
y-guyon Mar 24, 2026
7dbb3ef
Fix c-cpp CI for Windows (#69)
y-guyon Mar 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: configure
run: mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release ..
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- name: build
run: cmake --build build
- name: test
Expand All @@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: configure
run: mkdir build && cd build && cmake ..
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
- name: build
run: cmake --build build
- name: test
Expand All @@ -33,7 +33,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: configure
run: mkdir build && cd build && cmake ..
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
- name: build
run: cmake --build build --config Debug
- name: test
Expand Down
24 changes: 18 additions & 6 deletions .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,21 @@ jobs:
name: Formatting Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run clang-format style check for C/C++ programs.
uses: jidicula/clang-format-action@v4.11.0
with:
clang-format-version: '15'
check-path: 'IsoLib/libisomediafile'
- uses: actions/checkout@v4

- name: Install clang-format
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 18
sudo apt-get install -y clang-format-18

- name: Run clang-format check on IsoLib/libisomediafile
run: |
find IsoLib/libisomediafile \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) | \
xargs clang-format-18 --dry-run --Werror -style=file

- name: Run clang-format check on IsoLib/t35_tool
run: |
find IsoLib/t35_tool \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) | \
xargs clang-format-18 --dry-run --Werror -style=file
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,7 @@ doc/
*.code-workspace
# Local History for Visual Studio Code
.history/

# T35 Tool Test Output
TestData/t35_tool/output_all_modes/
TestData/t35_tool/output_smpte/
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,6 @@ if(NOT ISOBMFF_BUILD_LIB_ONLY)
add_subdirectory(IsoLib/isoiff_tool)
add_subdirectory(IsoLib/pcm_audio_example)
add_subdirectory(IsoLib/vvc_base)
add_subdirectory(IsoLib/t35_tool)
add_subdirectory(test)
endif()
2 changes: 1 addition & 1 deletion IsoLib/favs_example/src/hevc.c
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ u8* stripNALEmulation(u8* buffer, u32* bufferLen) {
return outBuffer;
}

int parseHEVCNal(FILE* input, u8** data, int* data_len) {
u32 parseHEVCNal(FILE* input, u8** data, u32* data_len) {
size_t startPos;
size_t NALStart = 0;
size_t NALEnd = 0;
Expand Down
2 changes: 1 addition & 1 deletion IsoLib/favs_example/src/hevc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ MP4Err hevc_parse_pps_minimal(BitBuffer *bb, struct hevc_pps* pps);
MP4Err hevc_parse_slice_header_minimal(BitBuffer *bb, struct hevc_poc* poc, struct hevc_slice_header* header,
struct hevc_sps* sps, struct hevc_pps* pps);
u8* stripNALEmulation(u8* buffer, u32* bufferLen);
int parseHEVCNal(FILE* input, u8** data, int* data_len);
u32 parseHEVCNal(FILE* input, u8** data, u32* data_len);
ISOErr analyze_hevc_stream(FILE* input, struct hevc_stream* stream);

#endif
12 changes: 6 additions & 6 deletions IsoLib/ipmp_example/src/protectAudioMovie.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ MP4Err addIPMPToolDescriptorUpdateToODAccessUnit( MP4Handle odAccessUnitH,
/
/ main function
/
/*=====*/
/ =====*/

int main( int argc, char **argv )
{
Expand Down Expand Up @@ -100,7 +100,7 @@ int main( int argc, char **argv )
/ protectMyAudioMovie
/ Protect the audio media track using an IPMP Tool specified by its IPMP_ToolID
/
/*=====*/
/ =====*/

MP4Err protectMyAudioMovie( char *inFilename, char *outFilename, u64 ipmpToolID )
{
Expand Down Expand Up @@ -355,7 +355,7 @@ MP4Err protectMyAudioMovie( char *inFilename, char *outFilename, u64 ipmpToolID
/ associateSampleDescWithIPMPToolPtr
/ Create the IPMP_ToolDecriptorPointer and add it to the media Sample Description
/
/*=====*/
/ =====*/

MP4Err associateSampleDescWithIPMPToolPtr( MP4Handle outMediaSampleDescrH,
u16 theIPMP_ToolDescriptorID) {
Expand Down Expand Up @@ -384,7 +384,7 @@ MP4Err associateSampleDescWithIPMPToolPtr( MP4Handle outMediaSampleDescrH,
/ addIPMPToolDescriptorUpdateToODAccessUnit
/ Create the IPMP_ToolDecriptorUpdate command and add it to an OD access unit
/
/*=====*/
/ =====*/

MP4Err addIPMPToolDescriptorUpdateToODAccessUnit( MP4Handle odAccessUnitH,
u16 ipmpToolDescriptorId,
Expand Down Expand Up @@ -437,7 +437,7 @@ MP4Err addIPMPToolDescriptorUpdateToODAccessUnit( MP4Handle odAccessUnitH,
/ protectSample
/ Protect one media access unit (or sample)
/
/*=====*/
/ =====*/

MP4Err protectSample(MP4Handle sampleH, u64 ipmpToolID) {

Expand All @@ -452,7 +452,7 @@ MP4Err protectSample(MP4Handle sampleH, u64 ipmpToolID) {
/ putToolListInIOD
/ Create the IPMP Tool List and put it in the IOD
/
/*=====*/
/ =====*/

MP4Err putToolListInIOD( MP4Movie theMovie, u64 theIpmpToolID) {

Expand Down
16 changes: 8 additions & 8 deletions IsoLib/isoiff_tool/src/HEVCDecoderConfigRecord.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,13 @@ MP4Err ISOIFF_CreateHEVCDecConfRecFromHandle(MP4Handle recordDataHandle,
// buffer += 4;
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_profile_compatibility_flags = (tmp8 << 24);
hevcDecConfRec->general_profile_compatibility_flags = ((u64)tmp8 << 24);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_profile_compatibility_flags |= (tmp8 << 16);
hevcDecConfRec->general_profile_compatibility_flags |= ((u64)tmp8 << 16);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_profile_compatibility_flags |= (tmp8 << 8);
hevcDecConfRec->general_profile_compatibility_flags |= ((u64)tmp8 << 8);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_profile_compatibility_flags |= tmp8;
Expand All @@ -350,19 +350,19 @@ MP4Err ISOIFF_CreateHEVCDecConfRecFromHandle(MP4Handle recordDataHandle,
// hevcDecConfRec->general_constraint_indicator_flags = tmp64 >> 16;
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags = tmp8 << 40;
hevcDecConfRec->general_constraint_indicator_flags = (u64)tmp8 << 40;
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags |= (tmp8 << 32);
hevcDecConfRec->general_constraint_indicator_flags |= ((u64)tmp8 << 32);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags |= (tmp8 << 24);
hevcDecConfRec->general_constraint_indicator_flags |= ((u64)tmp8 << 24);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags |= (tmp8 << 16);
hevcDecConfRec->general_constraint_indicator_flags |= ((u64)tmp8 << 16);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags |= (tmp8 << 8);
hevcDecConfRec->general_constraint_indicator_flags |= ((u64)tmp8 << 8);
memcpy(&tmp8, buffer, 1);
buffer += 1;
hevcDecConfRec->general_constraint_indicator_flags |= tmp8;
Expand Down
2 changes: 2 additions & 0 deletions IsoLib/libisomediafile/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ add_library(
src/MetaboxRelationAtom.c
src/MJ2BitsPerComponentAtom.c
src/MJ2ColorSpecificationAtom.c
src/MP4ColourInformationAtom.c
src/MJ2FileTypeAtom.c
src/MJ2HeaderAtom.c
src/MJ2ImageHeaderAtom.c
Expand Down Expand Up @@ -186,6 +187,7 @@ add_library(
src/SubSampleInformationAtom.c
src/SubsegmentIndexAtom.c
src/SyncSampleAtom.c
src/T35MetadataSampleEntry.c
src/TextMetaSampleEntry.c
src/TimeToSampleAtom.c
src/TrackAtom.c
Expand Down
93 changes: 89 additions & 4 deletions IsoLib/libisomediafile/src/ISOMovies.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ extern "C"
#define ISOOpenMovieInPlace MP4OpenMovieInPlace

struct MP4BoxedMetadataSampleEntry;
struct MP4T35MetadataSampleEntry;

/**
* @brief constants for the graphics modes (e.g. for MJ2SetMediaGraphicsMode)
Expand Down Expand Up @@ -311,7 +312,8 @@ extern "C"
#define ISOGetUserDataTypeCount MP4GetUserDataTypeCount
#define ISONewUserData MP4NewUserData
#define ISOCreateTrackReader MP4CreateTrackReader
#define ISOSetMebxTrackReader MP4SetMebxTrackReader
#define ISOSetMebxTrackReaderLocalKeyId MP4SetMebxTrackReaderLocalKeyId
#define ISOSelectFirstMebxTrackReaderKey MP4SelectFirstMebxTrackReaderKey
#define ISODisposeTrackReader MP4DisposeTrackReader
#define ISONewHandle MP4NewHandle
#define ISOSetHandleSize MP4SetHandleSize
Expand Down Expand Up @@ -800,13 +802,96 @@ extern "C"
* @param sampleEntryH input sample entry of the mebx track
* @param key_cnt number of local_key_id's
*/
ISO_EXTERN(ISOErr)
ISOGetMebxMetadataCount(MP4Handle sampleEntryH, u32 *key_cnt);
ISO_EXTERN(ISOErr) ISOGetMebxMetadataCount(MP4Handle sampleEntryH, u32 *key_cnt);

/**
* @brief Get metadata key configuration from a 'mebx' sample entry.
*
* Retrieves the key information at index @p idx from the MetadataKeyTableBox. Returns namespace,
* value, locale, setup data, and the local_key_id for this entry.
*
* @param sampleEntryH Handle containing the 'mebx' sample entry.
* @param idx Zero-based index of the key entry to query.
* @param local_key_id Output; receives the local_key_id for this key.
* @param key_namespace Output; receives the namespace FourCC.
* @param key_value Optional handle to receive the key value data.
* @param locale_string Optional; receives locale string if present.
* @param setupInfo Optional handle to receive setup information if present.
*
* @return ISOErr code: MP4NoErr on success, MP4BadDataErr if no key table, MP4NotFoundErr if not
* found, or other error codes.
*/
ISO_EXTERN(ISOErr)
ISOGetMebxMetadataConfig(MP4Handle sampleEntryH, u32 cnt, u32 *local_key_id, u32 *key_namespace,
ISOGetMebxMetadataConfig(MP4Handle sampleEntryH, u32 idx, u32 *local_key_id, u32 *key_namespace,
MP4Handle key_value, char **locale_string, MP4Handle setupInfo);

/*************************************************************************************************
* T.35 Metadata Track Functions
************************************************************************************************/

/**
* @brief Create a new T.35 metadata sample entry.
* @ingroup SampleDescr
*
* Creates a T35MetadataSampleEntry ('it35') with a T35CommonHeaderBox ('t35C') containing
* the specified T.35 prefix text.
*
* @param outSE Output; receives the created T35MetadataSampleEntry.
* @param dataReferenceIndex Data reference index (typically 1 for self-contained media).
* @param t35_prefix_text UTF-8 string conforming to format: T35Prefix[:T35Description]
* where T35Prefix is even number of uppercase hex digits (0-9, A-F).
* Example: "B500900001:SMPTE-ST2094-50"
* @return MP4Err code: MP4NoErr on success, MP4BadParamErr if validation fails.
*/
MP4_EXTERN(MP4Err)
ISONewT35SampleDescription(struct MP4T35MetadataSampleEntry **outSE, u32 dataReferenceIndex,
const char *t35_prefix_text);

/**
* @brief Create a complete T.35 timed metadata track.
* @ingroup Tracks
*
* Convenience function that creates a metadata track with MP4MetaHandlerType,
* adds a T35MetadataSampleEntry with the specified T.35 prefix, and optionally
* adds a track reference to a video track using the 'rndr' reference type.
*
* After calling this function, use MP4AddMediaSample() or similar functions to
* add T.35 metadata samples to the track.
*
* @param theMovie Input movie object.
* @param timescale Media timescale (typically matches video track timescale).
* @param t35_prefix_text UTF-8 T.35 prefix string (e.g., "B500900001:SMPTE-ST2094-50").
* @param videoTrack Optional video track for track reference (NULL if not needed).
* @param trackReferenceType Track reference type or 0 for no reference.
* @param outTrack Output; receives the created metadata track.
* @param outMedia Optional output; receives the created media (NULL if not needed).
* @return ISOErr code: MP4NoErr on success, error code otherwise.
*/
ISO_EXTERN(ISOErr)
ISONewT35MetadataTrack(MP4Movie theMovie, u32 timescale, const char *t35_prefix_text,
MP4Track videoTrack, u32 trackReferenceType, MP4Track *outTrack,
MP4Media *outMedia);

/**
* @brief Read the t35_identifier and description from a serialized T.35 sample entry handle.
* @ingroup SampleDescr
*
* Properly deserializes the handle returned by MP4GetMediaSampleDescription() and extracts
* the T.35 identifier bytes and optional description string. The caller is responsible for
* freeing *outIdentifier and *outDescription with free().
*
* @param sampleEntryH Handle containing the serialized 'it35' sample entry.
* @param outIdentifier Output; receives a newly allocated copy of the t35_identifier bytes.
* @param outIdentifierSize Output; receives the number of bytes in *outIdentifier.
* @param outDescription Optional output; receives a newly allocated description string, or NULL
* if no description is present. Pass NULL to ignore.
* @return MP4NoErr on success, MP4NotFoundErr if no identifier is present, MP4BadParamErr on
* invalid input.
*/
ISO_EXTERN(ISOErr)
ISOGetT35SampleEntryFields(MP4Handle sampleEntryH, u8 **outIdentifier, u32 *outIdentifierSize,
char **outDescription);

/*************************************************************************************************
* VVC Sample descriptions
************************************************************************************************/
Expand Down
Loading
Loading