Skip to content

feat: MXF index table infrastructure and restripe optimization#25

Open
nathanpbutler wants to merge 13 commits intomainfrom
feature/mxf-index-table
Open

feat: MXF index table infrastructure and restripe optimization#25
nathanpbutler wants to merge 13 commits intomainfrom
feature/mxf-index-table

Conversation

@nathanpbutler
Copy link
Copy Markdown
Owner

Summary

  • Phase 1: Direct-Write Optimization - Removes unnecessary read/seek pattern from restripe operations, reducing I/O by ~50% per System packet
  • Phase 2: Index Table Infrastructure - Adds PartitionPack and MxfIndex models for parsing MXF partition packs and index tables, enabling future frame-level seeking
  • Adds Index/HasIndex properties to MXF class with stub for index loading from footer partition

Changes

  • lib/Handlers/MXFHandler.cs - Optimized restripe methods, moved timebase validation to once-per-file
  • lib/Core/PartitionPack.cs - New model for parsing MXF partition pack data (big-endian)
  • lib/Core/MxfIndex.cs - New model for CBE/VBE index table offset calculations
  • lib/Keys.cs - Added partition pack and index table key constants
  • lib/Formats/MXF.cs - Added Index/HasIndex properties and LoadIndexTable stub

Test Plan

  • All 390 existing tests pass
  • New multi-frame restripe verification test
  • PartitionPack parsing tests (valid data, short data, zero footer)
  • MxfIndex offset calculation tests (CBE, VBE, bounds checking)

Design for improving restripe performance on large (10-100GB) MXF files:
- Phase 1: Direct-write optimization to eliminate redundant reads
- Phase 2: Index table support to skip sequential body scanning
10 tasks covering:
- Direct-write optimization (Tasks 1-4)
- Index table infrastructure (Tasks 5-10)
Establishes baseline behavior before direct-write optimization.
Verifies SMPTE timecodes are sequential after restriping.
Remove unnecessary read of current timecode value and seek-back
before writing. Reduces I/O operations by ~50% per System packet.
Apply same direct-write optimization to async restripe path.
Myriadbits validation now runs only on first System packet instead
of every packet. Further reduces per-frame I/O overhead.
Prepare for index table parsing by defining MXF partition pack keys
and index table segment key.
Parses partition pack data to extract footer offset and index info.
Supports both CBE (constant byte) and VBE (variable byte) index tables.
Provides GetEditUnitOffset and GetSystemPacketOffset for direct seeking.
Tests CBE and VBE offset calculations and bounds checking.
Adds HasIndex/Index properties and initial partition pack reading.
Full index table parsing to follow.
- Add FooterPartitionPackOpenIncomplete, ClosedIncomplete, OpenComplete keys
- Add EOF check in ValidateTimebaseOnce to match async version
Comment on lines +406 to +409
catch
{
return null; // Graceful fallback on any error
}

Check notice

Code scanning / CodeQL

Generic catch clause Note

Generic catch clause.

Copilot Autofix

AI 2 months ago

In general, to fix generic catch clauses, identify the set of exceptions that are realistically expected from the operations in the try block and catch those explicitly, possibly grouped by base type (e.g., IOException). Avoid catching non-CLS or catastrophic exceptions, and optionally rethrow unknown exceptions. This makes the intent clear and avoids silently handling unexpected errors.

For LoadIndexTable in lib/Formats/MXF.cs, the risky operations are: seeking and reading from a Stream (Input.Seek, Input.Read), allocating arrays, reading BER length, and parsing the partition pack (PartitionPack.Parse). The most appropriate categories of expected exceptions here are IOException (and derived types like EndOfStreamException) for stream problems and FormatException (or some parsing-related exception) for invalid partition/BER data. We want to preserve the current behavior of “on any expected error, just return null”, but we should not silently catch everything.

The best minimal-change fix is:

  • Replace the bare catch with one or more specific catch clauses, e.g.:
    • catch (IOException) for IO-related failures.
    • catch (FormatException) for malformed data during parsing/BER decoding.
  • Optionally, keep a final catch (Exception) that rethrows (throw;) if you want stricter behavior. However, that would change the method’s external behavior by no longer always returning null on unexpected errors. To avoid changing functionality, we should not add such a rethrow here.
  • Since there are no System.IO or System imports shown in the snippet, and IOException / FormatException live in System and System.IO, we must add using System; and using System.IO; at the top of MXF.cs.

Concretely:

  • In LoadIndexTable, replace:
        try
        {
            ...
        }
        catch
        {
            return null; // Graceful fallback on any error
        }

with:

        try
        {
            ...
        }
        catch (IOException)
        {
            return null; // Graceful fallback on I/O errors
        }
        catch (FormatException)
        {
            return null; // Graceful fallback on malformed MXF structures
        }
  • At the top of MXF.cs, add using System; and using System.IO; above or among the existing using declarations.

This keeps the method’s visible behavior (returning null on expected failures) while eliminating the generic catch clause.

Suggested changeset 1
lib/Formats/MXF.cs

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/lib/Formats/MXF.cs b/lib/Formats/MXF.cs
--- a/lib/Formats/MXF.cs
+++ b/lib/Formats/MXF.cs
@@ -1,5 +1,7 @@
+using System;
 using System.Buffers;
 using System.Diagnostics.CodeAnalysis;
+using System.IO;
 using System.Runtime.CompilerServices;
 using nathanbutlerDEV.libopx.Core;
 using nathanbutlerDEV.libopx.Enums;
@@ -403,10 +403,14 @@
             Input.Seek(originalPosition, SeekOrigin.Begin);
             return null; // Full implementation in next task
         }
-        catch
+        catch (IOException)
         {
-            return null; // Graceful fallback on any error
+            return null; // Graceful fallback on I/O errors
         }
+        catch (FormatException)
+        {
+            return null; // Graceful fallback on malformed MXF structures
+        }
     }
 
     /// <summary>
EOF
@@ -1,5 +1,7 @@
using System;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.CompilerServices;
using nathanbutlerDEV.libopx.Core;
using nathanbutlerDEV.libopx.Enums;
@@ -403,10 +403,14 @@
Input.Seek(originalPosition, SeekOrigin.Begin);
return null; // Full implementation in next task
}
catch
catch (IOException)
{
return null; // Graceful fallback on any error
return null; // Graceful fallback on I/O errors
}
catch (FormatException)
{
return null; // Graceful fallback on malformed MXF structures
}
}

/// <summary>
Copilot is powered by AI and may make mistakes. Always verify output.
@claude
Copy link
Copy Markdown

claude bot commented Jan 26, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant