-
Notifications
You must be signed in to change notification settings - Fork 255
[Depends][Bento4] Cleanups to remove some patches #1968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Code Review SummaryCritical Unsafe downcast in ParseTrafTfrf (src/samplereader/FragmentedSampleReader.cpp:613) Must Fix Accessing protected member via derived class hack (src/samplereader/FragmentedSampleReader.cpp:34-39) Medium Potential integer overflow in ReadGolomb (src/codechandler/AVCCodecHandler.cpp:28) |
|
@claude review please |
|
Claude finished @CastagnaIT's task in 1m 57s —— View job Code Review Complete
SummaryI've reviewed the PR which moves custom patches from the Bento4 fork to local code. The overall approach is sound and achieves the goal of reducing patch maintenance burden. I found the following issues: Critical Issues1. Integer Overflow Risk in ReadGolomb (src/codechandler/AVCCodecHandler.cpp:23-28)Issue: The condition Location: Details:
Recommendation: Change line 23 from: if (leadingZeros > 32)to: if (leadingZeros >= 32)Your Response: You mentioned this is copied from existing fork patches and out of scope. However, since you're moving the code locally, this is the perfect opportunity to fix it. The fix is trivial (one character change) and prevents undefined behavior. 2. FMP4UnknownUuidAtom Design Issue (src/samplereader/FragmentedSampleReader.cpp:34-39)Issue: The custom Location: Details:
Questions for Clarification:
Current Assessment: Without knowing the Bento4 API, I cannot determine if this approach is correct. However, the pattern of using inheritance to expose protected members is generally considered a code smell. If the base class doesn't provide access to the data, you might need:
Recommendation: Please verify whether base Bento4 provides Minor Issues3. Potential Type Mismatch in Dynamic Cast (src/samplereader/FragmentedSampleReader.cpp:613)Issue: Using Location: Details:
Recommendation:
Code Quality ObservationsPositive Aspects
Suggested Improvements
Testing RecommendationsSince this PR moves existing functionality:
ConclusionThe PR achieves its goal of moving patches locally, but there are two critical issues that need addressing:
Please address the overflow issue and clarify the UUID atom data access approach. |
|
@claude by reading your review: about: 2. FMP4UnknownUuidAtom Design Issue
about: 3. Potential Type Mismatch in Dynamic Cast |
|
Claude finished @CastagnaIT's task in 2m 14s —— View job Solutions for UUID Atom Data Access
AnalysisBased on your clarifications and the code review: Current Situation:
The Problem:
Proposed SolutionsSolution 1: Friend Class Approach (Not Viable)Create a friend accessor class that can access the protected member without inheritance tricks. Issue: This requires either:
Not recommended - requires modifying Bento4 headers. Solution 2: Same-Layout Derived Class with reinterpret_cast (Recommended)Keep your current // Keep the class as-is (lines 34-39)
class FMP4UnknownUuidAtom : public AP4_UnknownUuidAtom
{
public:
// Expose atom data
const AP4_DataBuffer& GetData() { return m_Data; }
};
// Fix ParseTrafTfrf (line 611-618)
void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)
{
// Cast to the base class first
auto* unknownUuidAtom = dynamic_cast<AP4_UnknownUuidAtom*>(uuidAtom);
if (!unknownUuidAtom)
{
LOG::LogF(LOGERROR, "Invalid atom type passed to ParseTrafTfrf. Expected AP4_UnknownUuidAtom.");
return;
}
// Use reinterpret_cast to treat it as our derived class
// This works because FMP4UnknownUuidAtom has the same memory layout
auto* accessor = reinterpret_cast<FMP4UnknownUuidAtom*>(unknownUuidAtom);
const AP4_DataBuffer& buf = accessor->GetData();
CCharArrayParser parser;
parser.Reset(buf.GetData(), buf.GetDataSize());
// ... rest of function unchanged ...
}Explanation:
Pros:
Cons:
Solution 3: Parse Atom Data Manually (Cleanest)Skip the high-level API entirely and parse the raw atom bytes: void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)
{
// UUID atoms have this structure:
// - 4 bytes: size
// - 4 bytes: type ('uuid')
// - 16 bytes: UUID
// - remaining: data payload
// Get raw atom data by seeking in the byte stream
AP4_LargeSize atomSize = uuidAtom->GetSize();
AP4_Position atomOffset = /* need to determine atom offset */;
const AP4_Size headerSize = 8 + 16; // size + type + uuid
if (atomSize <= headerSize)
{
LOG::LogF(LOGERROR, "TFRF atom too small");
return;
}
AP4_Size dataSize = static_cast<AP4_Size>(atomSize - headerSize);
AP4_DataBuffer buf;
buf.SetDataSize(dataSize);
// Read payload from byte stream
AP4_ByteStream* stream = m_lReader->GetByteStream();
AP4_Position savedPos;
stream->Tell(savedPos);
stream->Seek(atomOffset + headerSize);
AP4_Result result = stream->Read(buf.UseData(), dataSize);
stream->Seek(savedPos); // restore position
if (AP4_FAILED(result))
{
LOG::LogF(LOGERROR, "Failed to read TFRF atom data");
return;
}
// Now parse buf as before
CCharArrayParser parser;
parser.Reset(buf.GetData(), buf.GetDataSize());
// ... existing parsing code ...
}Pros:
Cons:
Challenge: You need the atom's position in the byte stream. The Solution 4: C-Style Cast (Simpler but Less Safe)A simpler variant of Solution 2: void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)
{
auto* unknownUuidAtom = dynamic_cast<AP4_UnknownUuidAtom*>(uuidAtom);
if (!unknownUuidAtom)
{
LOG::LogF(LOGERROR, "Invalid atom type passed to ParseTrafTfrf. Expected AP4_UnknownUuidAtom.");
return;
}
// Use C-style cast (equivalent to reinterpret_cast here)
const AP4_DataBuffer& buf = ((FMP4UnknownUuidAtom*)unknownUuidAtom)->GetData();
CCharArrayParser parser;
parser.Reset(buf.GetData(), buf.GetDataSize());
// ... rest unchanged ...
}This is essentially the same as Solution 2 but uses a C-style cast instead of My RecommendationGo with Solution 2 (reinterpret_cast approach) because:
If you want absolute correctness and long-term maintainability, go with Solution 3, but be aware it requires more investigation and code changes. Recommended Code ChangeReplace lines 611-622 in void CFragmentedSampleReader::ParseTrafTfrf(AP4_UuidAtom* uuidAtom)
{
// First verify we have an AP4_UnknownUuidAtom
auto* unknownUuidAtom = dynamic_cast<AP4_UnknownUuidAtom*>(uuidAtom);
if (!unknownUuidAtom)
{
LOG::LogF(LOGERROR, "Invalid atom type passed to ParseTrafTfrf. Expected AP4_UnknownUuidAtom.");
return;
}
// Access protected m_Data via reinterpret_cast to our derived accessor class.
// This works because FMP4UnknownUuidAtom has identical memory layout (no new data members).
// After removing fork patches, AP4_UnknownUuidAtom::GetData() no longer exists,
// so we use this pattern to access the protected m_Data member.
auto* accessor = reinterpret_cast<FMP4UnknownUuidAtom*>(unknownUuidAtom);
const AP4_DataBuffer& buf = accessor->GetData();
CCharArrayParser parser;
parser.Reset(buf.GetData(), buf.GetDataSize());
if (parser.CharsLeft() < 5)
{
LOG::LogF(LOGERROR, "Wrong data length on TFRF atom.");
return;
}
// ... rest of function remains the same ...This change:
Let me know which solution you prefer, or if you'd like me to provide a complete implementation of Solution 3 (manual parsing). |
Moved locally custom bento4 fork patch
Moved locally custom bento4 fork patch
Moved locally this method to lighten the patches on bento4 fork
2b36f91 to
da85c80
Compare
|
@claude i updated PR with your hints, please do a final review |
|
Claude finished @CastagnaIT's task in 2m 9s —— View job Final Code Review
SummaryGreat work addressing my previous review feedback! The implementation looks correct and the PR is ready to merge. All critical issues have been properly resolved. What Was Fixed✅ 1. FMP4UnknownUuidAtom Casting Issue (RESOLVED)Previous Issue: The code used Current Implementation (src/samplereader/FragmentedSampleReader.cpp:613-621): auto* unknownUuidAtom = dynamic_cast<AP4_UnknownUuidAtom*>(uuidAtom);
if (!unknownUuidAtom)
{
LOG::LogF(LOGERROR, "Invalid atom type passed to ParseTrafTfrf. Expected AP4_UnknownUuidAtom.");
return;
}
auto* accessor = reinterpret_cast<FMP4UnknownUuidAtom*>(unknownUuidAtom);
const AP4_DataBuffer& buf{accessor->GetData()};Verdict: ✅ Perfect implementation! This is exactly the solution I recommended (Solution 2 from my previous review):
✅ 2. ReadGolomb Integer Overflow (RESOLVED)Previous Issue: The condition Current Implementation (src/codechandler/AVCCodecHandler.cpp:23-24): if (leadingZeros >= 32)
return 0; // safeguardVerdict: ✅ Fixed correctly! The edge case at Additional Changes Reviewed3. Code Organization and CleanupAVCCodecHandler Member Variables (src/codechandler/AVCCodecHandler.h:27-28):
NALU Length Size Initialization (src/codechandler/CodecHandler.h:67):
WVTT Sample Format (src/samplereader/FragmentedSampleReader.cpp:41, 595):
ReadGolomb Method (src/codechandler/AVCCodecHandler.cpp:17-34):
Code Quality Improvements:
Code Quality AssessmentStrengths
No Issues FoundI've carefully reviewed all changes and found no issues. The code is:
Technical Deep DiveFor those interested in why the reinterpret_cast solution works: The Pattern:
Why It's Safe:
Why It's Necessary:
Testing RecommendationsSince the changes involve:
These are the same recommendations from my previous review, and they still apply. ConclusionStatus: ✅ APPROVED - Ready to merge All issues from my previous review have been correctly addressed:
The PR successfully achieves its goal of moving Bento4 fork patches to local code while maintaining correctness and code quality. Excellent work! 🎉 |
6d9e1ae to
8b89246
Compare
8b89246 to
acf8233
Compare
Description
move some custom patches from our fork of bento4 locally in order to reduce the number of patches to maintain
NOTE: already moved locally "LinearReader: GetSample, SeekSample, Reset methods" by last PR's merged
BENTO4 version bump to new branch: 1.6.0-641-4-Piers (cleanup only, not updated from upstream)
https://github.com/xbmc/Bento4/tree/1.6.0-641-4-Piers
Motivation and context
superseeds PR #1654
How has this been tested?
Screenshots (if appropriate):
Types of change
Checklist: