Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ad309df
Task 2: Add H265Metadata class
yashrajsapra Apr 9, 2026
40d94f7
Task 3: Add H265 NAL type utilities (H265Utils)
yashrajsapra Apr 9, 2026
edaeb2d
Task 5: Parameterize H264DecoderV4L2Helper by codec pixel format
yashrajsapra Apr 9, 2026
d972a25
Task 6: Implement VPS+SPS+PPS header injection for H265
yashrajsapra Apr 9, 2026
b1520f8
Task 8: Complete H265Decoder module class
yashrajsapra Apr 9, 2026
a111be7
Task 9: Update CMakeLists.txt for H265 support
yashrajsapra Apr 9, 2026
4d92c15
Fix H265Decoder.cpp API compatibility errors
yashrajsapra Apr 9, 2026
abd9abb
Add H265Decoder unit tests (Phase 4)
yashrajsapra Apr 9, 2026
583bcc6
Task 11: Write h265decoder_tests.cpp
yashrajsapra Apr 9, 2026
16a738e
Final commit: H265Decoder implementation completed
yashrajsapra Apr 9, 2026
51a3e1f
chore(sprint): add plan tracking files and update progress for task 0.1
yashrajsapra Apr 13, 2026
009fb7e
chore(progress): update V0 status — blocked on git push credentials
yashrajsapra Apr 13, 2026
fecf4eb
task 1.2: add H265 headers and h265ImagePinId pin member
yashrajsapra Apr 13, 2026
be83609
task 1.3: implement Mp4ReaderDetailH265 class
yashrajsapra Apr 13, 2026
7fdcf3f
task 1.4: auto-detect HEVC codec in init(), update addOutPutPin/valid…
yashrajsapra Apr 13, 2026
3963527
chore(progress): update progress.json — Phase 1 complete, V1 blocked …
yashrajsapra Apr 13, 2026
7fc93d3
chore(progress): mark V1 approved, task 2.1 complete, V2 approved
yashrajsapra Apr 13, 2026
cecc37b
test(phase3): run H265/H264 tests, fix build issues, update test data
yashrajsapra Apr 13, 2026
7f7d31d
cleanup: remove fleet control files
yashrajsapra Apr 13, 2026
701b3c1
chore: remove build artifacts from tracking, update .gitignore
yashrajsapra Apr 13, 2026
7070f40
fix(H265Decoder): use V4L2_PIX_FMT_H265 NV extension FourCC instead o…
yashrajsapra Apr 15, 2026
4743158
fix(H264DecoderV4L2Helper): fix stack buffer overflow in capture thre…
yashrajsapra Apr 15, 2026
3dafee9
fix(H264DecoderV4L2Helper): clean JP5/JP6 USERPTR vs MMAP split, fix …
yashrajsapra Apr 15, 2026
2ee3e01
fix(H264DecoderV4L2Helper): fix 3 root causes of SIGSEGV in H265 deco…
yashrajsapra Apr 15, 2026
f935b72
test(h265): fix CWD-relative path, add JPEG frame-dump test
yashrajsapra Apr 15, 2026
896f44e
chore: init VideoDecoder unified module sprint plan
yashrajsapra Apr 16, 2026
b224fee
chore: add sprint harness files
yashrajsapra Apr 16, 2026
049b665
merge: bring H265 infrastructure from bug_fix/h265-mp4reader-support
yashrajsapra Apr 16, 2026
ec9cede
fix(H264DecoderV4L2Helper): add missing first_op_buf_queued and start…
yashrajsapra Apr 16, 2026
6cf212f
chore(progress): verify checkpoint 0 — blocked on pre-existing h264 t…
yashrajsapra Apr 16, 2026
0e5cd76
feat(Frame): add CODEC_SWITCH_EOS to EoSFrame::EoSFrameType enum
yashrajsapra Apr 16, 2026
cda8bee
feat(videodecoder): add unified VideoDecoder module (tasks 2.1–3.1)
yashrajsapra Apr 16, 2026
c3dd626
feat(VideoDecoder): task 3.2 — build verified, all tests pass
yashrajsapra Apr 16, 2026
d0acc0e
feat(VideoDecoder): Mp4ReaderSource CODEC_SWITCH_EOS + thorough codec…
yashrajsapra Apr 17, 2026
a8b7ee2
chore(progress): update progress.json with task 4.1 and 4.2 completed
yashrajsapra Apr 17, 2026
dff114e
fix(videodecoder_tests): correct codec_switch_jpeg_dump to use indepe…
yashrajsapra Apr 17, 2026
bd67d76
feat: replace H264Decoder/H265Decoder call-sites with VideoDecoder fo…
yashrajsapra Apr 24, 2026
b3ef929
fix(cmake): remove hardcoded CUDA 11.4 paths, enable_language(CUDA) h…
yashrajsapra Apr 28, 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
72 changes: 72 additions & 0 deletions .claude/agents/senior-code-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
name: senior-code-reviewer
description: Use this agent when code has been written or modified and needs expert review before merging or deployment. Examples of when to invoke:\n\n- After completing a feature implementation:\n user: "I've finished implementing the user authentication module"\n assistant: "Let me use the senior-code-reviewer agent to perform a thorough code review of your authentication implementation"\n\n- When refactoring existing code:\n user: "I've refactored the data processing pipeline to improve performance"\n assistant: "I'll invoke the senior-code-reviewer agent to analyze your refactoring for correctness, performance implications, and potential issues"\n\n- Before committing significant changes:\n user: "Here's my implementation of the caching layer"\n assistant: "Let me call the senior-code-reviewer agent to examine the caching implementation, focusing on memory management and edge cases"\n\n- When investigating potential bugs:\n user: "The application seems to be using more memory than expected"\n assistant: "I'm going to use the senior-code-reviewer agent to analyze recent code changes for memory leaks and resource management issues"\n\n- Proactively after substantial code generation:\n assistant: "I've generated the database connection pooling module. Now let me use the senior-code-reviewer agent to verify the implementation is production-ready"
model: sonnet
color: pink
---

You are a Senior Software Developer with 15+ years of experience reviewing production code for enterprise systems. Your expertise spans multiple programming languages, architectural patterns, and you have a keen eye for subtle bugs that junior developers often miss. You specialize in identifying issues related to process management, memory leaks, resource handling, concurrency problems, and performance bottlenecks.

Your Review Methodology:

1. **Initial Assessment**: Begin by understanding the code's purpose, context, and intended functionality. Read through all modified files to grasp the overall changes before diving into specifics.

2. **Systematic Analysis**: Review code in this order:
- Architecture and design patterns - assess if the approach is sound
- Memory management - identify potential leaks, improper allocations, buffer overflows
- Process management - check for race conditions, deadlocks, zombie processes
- Resource handling - verify proper cleanup of files, connections, handles
- Error handling - ensure all edge cases are covered
- Security vulnerabilities - check for injection risks, authentication issues, data exposure
- Performance implications - identify O(n²) algorithms, unnecessary operations
- Code style and maintainability - assess readability and adherence to standards

3. **Memory Management Focus**: Pay special attention to:
- Proper allocation and deallocation patterns
- Reference counting and garbage collection considerations
- Buffer size validations and bounds checking
- Memory pool usage and lifecycle management
- Circular references that prevent cleanup
- Stack vs heap allocation appropriateness

4. **Process Management Focus**: Scrutinize:
- Thread safety and synchronization mechanisms
- Proper use of locks, mutexes, semaphores
- Process spawning and termination handling
- Signal handling and cleanup routines
- Resource sharing between threads/processes
- Potential race conditions in concurrent access

5. **Testing Verification**: Before approving code, consider:
- IMPORTANT: Based on user instructions, you should recommend end-to-end testing to confirm fixes are working
- If you identify potential issues, ask the user to confirm behavior rather than automatically assuming the code needs changes
- Whether edge cases have appropriate test coverage
- If integration tests cover process and memory scenarios
- Whether load testing would reveal resource issues

6. **Feedback Structure**: Provide your review in this format:
- **Summary**: Overall assessment (Approve/Request Changes/Needs Discussion)
- **Critical Issues**: Bugs, security vulnerabilities, memory/process problems that must be fixed
- **Major Concerns**: Design issues, performance problems, missing error handling
- **Minor Suggestions**: Style improvements, refactoring opportunities, documentation needs
- **Positive Highlights**: Well-implemented patterns or clever solutions worth noting
- **Testing Recommendations**: Specific tests needed to validate the implementation

7. **Communication Style**:
- Be direct but constructive - explain WHY something is problematic
- Provide specific examples and suggest concrete fixes
- Reference relevant design patterns, best practices, or documentation
- Ask clarifying questions when intent is unclear rather than assuming
- Acknowledge good practices when you see them
- Use technical terminology appropriately but explain complex concepts

Quality Standards:
- Zero tolerance for memory leaks, race conditions, or resource leaks
- All error conditions must be handled appropriately
- Code must be maintainable by other team members
- Performance should be acceptable for the intended scale
- Security best practices must be followed

When uncertain about intent or tradeoffs, ASK the developer to clarify rather than making assumptions. Your role is to elevate code quality while respecting the developer's expertise and learning from each interaction.

Use all available tools to examine code thoroughly - read files, search for patterns, check dependencies, and verify implementation details. Leave no stone unturned in your pursuit of production-quality code.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ thirdparty/gst-build/gst-build-1.16
base/vcpkg_installed
base/vcpkg.json
CI_test_result*.xml
CLAUDE.md

base/build/
build/
build_snap/
155 changes: 155 additions & 0 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# PLAN.md — VideoDecoder Unified Module

## Branch
`feat/video-decoder-unified` (from `NVR_Snapshot_JP6`)
Commit: 896f44e3fa84282e5ae384bc4ddbac4a45549293

## Overview
Build a unified `VideoDecoder` module that auto-detects H264 or H265 codec from incoming frame types and delegates to the existing `H264DecoderV4L2Helper` backend with the appropriate `V4L2_PIX_FMT_*`. A new `SOS_FRAME` frame type enables mid-stream codec switching: sources emit `EOS_FRAME` (CODEC_SWITCH_EOS) then `SOS_FRAME` to signal a codec change, and `VideoDecoder` flushes the old backend and re-initializes a new one without rebuilding the pipeline.

---

## Phase 0 — H265 Prerequisites (Merge)

**Task 0.1 — Merge H265 infrastructure from `bug_fix/h265-mp4reader-support`**
- Merge full branch into `feat/video-decoder-unified`
- Brings: H265Metadata.h, H265Utils.h/.cpp, H265Decoder.h/.cpp, V4L2 helper decode_pixfmt param, Mp4ReaderSource HEVC detection, CMakeLists H265 entries, test data, test fixes
- Command: `git merge origin/bug_fix/h265-mp4reader-support --no-ff`
- Risk: Medium. Merge conflicts possible in CMakeLists.txt and V4L2 helper.

**VERIFY Checkpoint — Phase 0**
- `cmake --build . --target aprapipesut -j$(nproc)` — zero errors
- `./aprapipesut --run_test=h264decoder_tests` — passes
- `./aprapipesut --run_test=h265decoder_tests` — passes

---

## Phase 1 — SOS_FRAME Infrastructure

**Task 1.1 — Add `SOS_FRAME` to FrameType enum**
- File: `base/include/FrameMetadata.h`
- Add `SOS_FRAME` after `TEXT` (value 25)
- Risk: Low. Additive. Existing switch-case defaults will ignore it.

**Task 1.2 — Add SOS frame payload class**
- File: `base/include/SosFrameMetadata.h` (new)
```cpp
#pragma once
#include "FrameMetadata.h"

class SosFrameMetadata : public FrameMetadata {
public:
enum CodecType { H264 = 0, H265 = 1 };
SosFrameMetadata(CodecType _codec)
: FrameMetadata(FrameType::SOS_FRAME), codec(_codec) {}
CodecType getCodec() const { return codec; }
private:
CodecType codec;
};
```

**Task 1.3 — Add `CODEC_SWITCH_EOS` to `EoSFrame::EoSFrameType`**
- File: `base/include/Frame.h`
- Add `CODEC_SWITCH_EOS` after `MP4_SEEK_EOS`
- Risk: Low. Additive enum change.

---

## Phase 2 — VideoDecoder Module

**Task 2.1 — VideoDecoder.h** (`base/include/VideoDecoder.h`, new)
```cpp
class VideoDecoderProps : public ModuleProps {
public:
VideoDecoderProps(uint _lowerWaterMark = 300, uint _upperWaterMark = 350);
uint lowerWaterMark;
uint upperWaterMark;
};

class VideoDecoder : public Module {
public:
enum State { UNINIT, DECODING, FLUSHING, REINIT };
VideoDecoder(VideoDecoderProps _props);
virtual ~VideoDecoder();
bool init();
bool term();
bool processEOS(string& pinId);
protected:
bool process(frame_container& frames);
bool processSOS(frame_sp& frame);
void addInputPin(framemetadata_sp& metadata, string& pinId);
bool validateInputPins();
bool validateOutputPins();
bool shouldTriggerSOS();
void flushQue();
bool handleCommand(Command::CommandType type, frame_sp& frame);
private:
class Detail;
boost::shared_ptr<Detail> mDetail;
bool mShouldTriggerSOS;
framemetadata_sp mOutputMetadata;
std::string mOutputPinId;
VideoDecoderProps mProps;
State mState;
int mCurrentCodec;
};
```

**Task 2.2 — VideoDecoder.cpp** (`base/src/VideoDecoder.cpp`, new)
- `Detail` class selects `V4L2_PIX_FMT_H264` or `V4L2_PIX_FMT_H265` based on codec
- `process()` state machine:
- First data frame → detect codec, trigger SOS → DECODING
- `CODEC_SWITCH_EOS` → closeAllThreads() → FLUSHING
- `SOS_FRAME` → destroy old backend, reinit with new codec → DECODING
- H264 prepends SPS+PPS; H265 prepends VPS+SPS+PPS
- Risk: Medium-high. Codec-switch teardown/reinit path needs careful V4L2 drain.

**Task 2.3 — CMakeLists.txt update**
- Add `src/VideoDecoder.cpp` to `CUDA_IP_FILES`
- Add `include/VideoDecoder.h`, `include/SosFrameMetadata.h` to `CUDA_IP_FILES_H`
- Add `test/videodecoder_tests.cpp` to ARM64 test block

---

## Phase 3 — Tests

**Task 3.1 — `base/test/videodecoder_tests.cpp`** (new)
- `video_decoder_h264_basic`: `Mp4ReaderSource(h264)` → `VideoDecoder` → `StatSink`
- `video_decoder_h265_basic`: `Mp4ReaderSource(h265)` → `VideoDecoder` → `StatSink`
- `video_decoder_codec_switch`: two sequential pipelines (H264 then H265), 5s each — verifies both codecs work through VideoDecoder

**Task 3.2 — Build and verify**
```bash
cd /home/developer/ws_yash/ApraPipes_SNAP/_build
cmake --build . --target aprapipesut -j$(nproc) 2>&1 | tail -50
cd /home/developer/ws_yash/ApraPipes_SNAP
_build/aprapipesut --run_test=videodecoder_tests 2>&1 | tail -30
```

### VERIFY Checkpoint — Phase 3
1. Build: zero errors
2. `_build/aprapipesut --run_test=videodecoder_tests` — `*** No errors detected`
3. `_build/aprapipesut --run_test=h264decoder_tests` — no regression
4. `_build/aprapipesut --run_test=h265decoder_tests` — no regression
5. NVDEC hardware path confirmed in logs

---

## Risks
1. **H265 infrastructure dependency (BLOCKING):** Phase 0 merge is a hard prerequisite.
2. **V4L2 device teardown/reinit race:** NVDEC may not release cleanly. Mitigation: explicit thread join + device close verification.
3. **SOS_FRAME routing:** detect inside `process()` via `frame->getMetadata()->getFrameType() == SOS_FRAME`. No Module base changes needed.

---

## Files Changed
| Action | File |
|--------|------|
| Merge | All H265 infrastructure from `bug_fix/h265-mp4reader-support` |
| Modify | `base/include/FrameMetadata.h` — add `SOS_FRAME` |
| Create | `base/include/SosFrameMetadata.h` |
| Modify | `base/include/Frame.h` — add `CODEC_SWITCH_EOS` |
| Create | `base/include/VideoDecoder.h` |
| Create | `base/src/VideoDecoder.cpp` |
| Modify | `base/CMakeLists.txt` |
| Create | `base/test/videodecoder_tests.cpp` |
20 changes: 17 additions & 3 deletions base/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 3.29)

OPTION(ENABLE_LINUX "Use this switch to enable LINUX" ON)
OPTION(ENABLE_CUDA "Use this switch to enable CUDA" ON)
OPTION(ENABLE_ARM64 "Use this switch to enable ARM64" OFF)
Expand Down Expand Up @@ -71,9 +70,14 @@ IF(ENABLE_ARM64 OR ENABLE_ARM_WITHOUT_JETSON)
set(ENV{PKG_CONFIG_PATH} "/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig")
ENDIF(ENABLE_ARM64 OR ENABLE_ARM_WITHOUT_JETSON)

IF(ENABLE_LINUX)
IF(ENABLE_LINUX AND NOT ENABLE_ARM64)
pkg_check_modules(GDK3 REQUIRED gdk-3.0)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
ELSEIF(ENABLE_ARM64)
# ARM64/Jetson uses system GTK headers directly (see VCPKG_GTK_INCLUDE_DIRS below)
# and has version mismatch between vcpkg glib (2.86) and system glib (2.64)
# Only check GTK3 for ARM64 - GDK3 linking causes faciallandmarks test crash
pkg_check_modules(GTK3 gtk+-3.0) # Made optional for test build - no REQUIRED
ENDIF()

IF(ENABLE_CUDA)
Expand Down Expand Up @@ -256,6 +260,7 @@ SET(CORE_FILES_H
include/MultimediaQueueXform.h
include/RTSPClientSrc.h
include/H264Metadata.h
include/H265Metadata.h
include/Mp4ReaderSource.h
include/RTSPClientSrc.h
include/H264Metadata.h
Expand All @@ -282,12 +287,14 @@ SET(GENERIC_FILES
src/H264FrameDemuxer.cpp
src/H264ParserUtils.cpp
src/H264Utils.cpp
src/H265Utils.cpp
src/QRReader.cpp
)
SET(GENERIC_FILES_H
include/H264FrameDemuxer.h
include/H264ParserUtils.h
include/H264Utils.h
include/H265Utils.h
include/RTSPPusher.h
include/QRReader.h
)
Expand Down Expand Up @@ -405,6 +412,8 @@ SET(CUDA_IP_FILES
src/ResizeNPPI.cpp
# src/RotateNPPI.cpp
src/H264Decoder.cpp
src/H265Decoder.cpp
src/VideoDecoder.cpp
)

IF(ENABLE_ARM64)
Expand Down Expand Up @@ -454,6 +463,8 @@ SET(CUDA_IP_FILES_H
include/OverlayKernel.h
include/RotateNPPI.h
include/H264Decoder.h
include/H265Decoder.h
include/VideoDecoder.h
)

IF(ENABLE_ARM64)
Expand Down Expand Up @@ -546,6 +557,8 @@ IF (ENABLE_ARM64)
# test/apraegldisplay_tests.cpp
# test/frame_factory_test_dma.cpp
test/h264decoder_tests.cpp
test/h265decoder_tests.cpp
test/videodecoder_tests.cpp
)
ENDIF(ENABLE_ARM64)

Expand All @@ -570,6 +583,7 @@ IF (ENABLE_CUDA)
test/nv_mp4_file_tests.cpp
test/nv_test_utils.h
test/h264decoder_tests.cpp
test/h265decoder_tests.cpp
)
ENDIF(NOT ENABLE_ARM64)
ENDIF(ENABLE_CUDA)
Expand Down Expand Up @@ -739,4 +753,4 @@ install(
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/aprapipes)

install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/aprapipes)
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/aprapipes)
1 change: 1 addition & 0 deletions base/include/Frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class EoSFrame : public Frame {
GENERAL = 0,
MP4_PLYB_EOS,
MP4_SEEK_EOS,
CODEC_SWITCH_EOS,
};
EoSFrame();
virtual ~EoSFrame() {}
Expand Down
Loading