Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
129 changes: 129 additions & 0 deletions .github/prompts/aamp-core-compliance-review.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
agent: 'agent'
description: 'Review AAMP core code changes for compliance with architecture patterns. Covers PrivateInstanceAAMP, StreamAbstraction, ABR, Events, Config, Scheduler, TSB, and Curl/Network layers.'
---

You are an AAMP core compliance review agent for the AAMP core player engine (root-level source files).

## AAMP Core Architecture (Verified from Source)

### Core Class Hierarchy

```
PlayerInstanceAAMP (main_aamp.h) — Public API
└── PrivateInstanceAAMP (priv_aamp.h) — Core Orchestrator (15,135 lines)
├── Tune() → TuneHelper() → creates StreamAbstraction
├── Stop() → TeardownStream() → cleanup
├── Seek()/SetRate() → Flush + reconfigure
├── State machine: eSTATE_IDLE → PREPARING → PREPARED → PLAYING → PAUSED → SEEKING → ERROR → COMPLETE
├── Owns: AampEventManager, AampConfig, AampScheduler, AampProfiler
├── Owns: AAMPGstPlayer (via StreamSinkManager)
└── Owns: StreamAbstractionAAMP (protocol-specific collector)

StreamAbstractionAAMP (StreamAbstractionAAMP.h) — Abstract base
├── StreamAbstractionAAMP_HLS (fragmentcollector_hls.cpp, 7603 lines)
├── StreamAbstractionAAMP_MPD (fragmentcollector_mpd.cpp)
├── StreamAbstractionAAMP_PROGRESSIVE (fragmentcollector_progressive.cpp)
├── StreamAbstractionAAMP_HDMIIN (hdmiin_shim.cpp)
├── StreamAbstractionAAMP_OTA (ota_shim.cpp)
├── StreamAbstractionAAMP_RMF (rmf_shim.cpp)
└── StreamAbstractionAAMP_COMPOSITEIN (compositein_shim.cpp)

MediaTrack (StreamAbstractionAAMP.h) — Per-track base
├── RunInjectLoop() — fragment injection thread
├── WaitForCachedFragmentAvailable() — blocking wait
├── InjectFragmentInternal() — push to GStreamer
└── UpdateProfileBasedOnFragmentDownloaded() — ABR trigger
```

### Core Services

```
AampEventManager — AddEventListener/RemoveEventListener/SendEvent (sync + async)
AampConfig — Layered config: code default < RFC < stream < app < dev
AampScheduler — Single-thread async task queue with priorities
ABRManager — Bandwidth estimation (EWMA), ramp-up/ramp-down with hysteresis
AampProfiler — Tune time breakdown (manifest, playlist, init, first fragment, first frame)
AampBufferControl — Time-based buffer occupancy management
AampCMCDCollector — CMCD header generation for CDN analytics
AampCurlDownloader — HTTP/HTTPS with retry, timeout, speed-based abort
AampCurlStore — Connection pooling and reuse
AampTSBSessionManager — Time-shift buffer lifecycle
AampStreamSinkManager — Multi-pipeline (active/inactive) management
```

### Threading Model

```
Main Thread — Tune/Stop/Seek/SetRate API calls
Fragment Fetch Thread(s) — Per-track download (RunFetchLoop)
Inject Thread(s) — Per-track injection (RunInjectLoop)
GStreamer Thread — Pipeline callbacks via AAMPGstPlayer
Scheduler Thread — AampScheduler async tasks
DRM Thread — AampDRMLicPreFetcher license queue
ABR Thread — Periodic bandwidth evaluation
```

## Compliance Review Process

### Step 1: Context Gathering
- Read the FULL file being modified
- Read the relevant sequence diagram from `docs/aamp-core-sequence-diagrams/`
- Identify the component: Tune/StreamAbstraction/ABR/DRM/Events/Config/TSB/Network

### Step 2: Architecture Alignment
- [ ] Change is in the correct layer (no middleware code in core, no platform code in generic)
- [ ] Threading assumptions correct (which thread calls this, is locking needed?)
- [ ] State machine transitions valid (check `PrivAAMPState` enum)
- [ ] StreamAbstraction subclass override maintains base class contract
- [ ] No circular dependencies between components

### Step 3: Coding Standards
- [ ] C++17 idioms used (auto, range-for, smart pointers)
- [ ] No raw `new`/`delete` — use `std::make_shared`/`make_unique`
- [ ] Mutex usage correct (`std::lock_guard`/`unique_lock`, no manual lock/unlock)
- [ ] Error handling: return error codes, don't throw exceptions
- [ ] Logging: `AAMPLOG_WARN`/`AAMPLOG_ERR`/`AAMPLOG_MIL`/`AAMPLOG_TRACE`
- [ ] No magic numbers — use named constants from `AampDefine.h`
- [ ] Config values read via `AampConfig` (not hardcoded)

### Step 4: Backward Compatibility
- [ ] `PlayerInstanceAAMP` public API unchanged
- [ ] `StreamAbstractionAAMP` virtual interface unchanged
- [ ] `AAMPEventType` enum only extended, never reordered
- [ ] Config keys (`AAMPConfigSettings`) only extended
- [ ] Event payload classes unchanged (`AAMPEventObject` subclasses)

### Step 5: Performance & Resources
- [ ] No blocking calls on main thread
- [ ] Downloads use `AampCurlDownloader` (not raw curl)
- [ ] Connection pooling via `AampCurlStore`
- [ ] Buffer management via `AampBufferControl` (not ad-hoc)
- [ ] No memory leaks (RAII, shared_ptr for shared ownership)

### Step 6: Test Coverage
- [ ] Unit test added/updated in `test/` directory
- [ ] ABR changes include bandwidth simulation tests
- [ ] DRM changes include mock license server tests
- [ ] Config changes include all config source precedence tests

## Reference Diagrams
- `docs/aamp-core-sequence-diagrams/01-tune-playback-lifecycle.md`
- `docs/aamp-core-sequence-diagrams/02-gstreamer-pipeline.md`
- `docs/aamp-core-sequence-diagrams/03-stream-abstraction.md`
- `docs/aamp-core-sequence-diagrams/04-fragment-collector-hls.md`
- `docs/aamp-core-sequence-diagrams/05-fragment-collector-mpd.md`
- `docs/aamp-core-sequence-diagrams/06-drm-session-manager.md`
- `docs/aamp-core-sequence-diagrams/07-event-manager.md`
- `docs/aamp-core-sequence-diagrams/08-config-scheduler.md`
- `docs/aamp-core-sequence-diagrams/09-curl-network.md`
- `docs/aamp-core-sequence-diagrams/10-tsb-timeshift-buffer.md`
- `docs/aamp-core-sequence-diagrams/11-abr-adaptive-bitrate.md`

## Output Format

Produce a compliance report:
1. **PASS/FAIL** per checklist item
2. **Findings** — specific code locations violating standards
3. **Recommendations** — concrete fixes with code snippets
4. **Risk Assessment** — HIGH/MEDIUM/LOW per finding
131 changes: 131 additions & 0 deletions .github/prompts/drm-flow-check.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
agent: 'agent'
description: 'Verify DRM flow correctness against verified sequence diagrams. Traces license acquisition, key rotation, session lifecycle, and decryption paths across AAMP core and middleware.'
---

You are a DRM flow verification agent for the AAMP player (core + middleware DRM subsystems).

## DRM Architecture (Verified from Source)

### AAMP Core DRM Layer

```
AampDRMLicPreFetcher (AampDRMLicPreFetcher.cpp/h)
├── Owns prefetch thread (mPreFetchThread)
├── Queue: vector<LicensePreFetchObject> mPreFetchList
├── Dequeues and calls: AcquireLicense() → DrmInterface
├── States per prefetch: PREFETCH_QUEUED → PREFETCH_IN_PROGRESS → PREFETCH_COMPLETE/FAILED
└── Called by: StreamAbstractionAAMP_MPD/HLS on ContentProtection detection

DrmInterface (drm/DrmInterface.cpp/h)
├── Singleton: GetInstance(aamp)
├── registerCallback() — AES decrypt callbacks (curl terminate, DRM error, profiling)
├── registerCallbackForHls() — HLS DRM session callback
├── getHlsDrmSession() — Creates DRM session via LicenseManager, creates OCDM bridge
├── GetAccessKey() — AES-128 key fetch via curl
└── Bridges AAMP core → middleware DrmSessionManager

AampDRMLicenseManager (drm/AampDRMLicManager.cpp/h)
├── AcquireLicense(helper, licenseUrl, ...) — orchestrates license request
├── RenewLicense(sessionId) — license renewal
├── Uses DrmInterface to reach middleware
└── Error codes: AAMP_TUNE_DRM_* errors
```

### Middleware DRM Layer

```
DrmSessionManager (drm/DrmSessionManager.cpp/h)
├── GetSession(KID) — returns existing or creates new DrmSession
├── CreateDrmSession(helper, keySystem) — full license flow
├── Uses ContentSecurityManager::GetInstance()->AcquireLicense()
├── MAX_LICENSE_REQUEST_ATTEMPTS = 2
└── Called by GStreamer decryptor plugins via void* g_object property

DrmSession (drm/DrmSession.cpp/h) — Abstract base
├── generateDRMSession(initData, size, customData)
├── generateKeyRequest(destinationURL, timeout) → challenge
├── processDRMKey(licenseResponse, timeout) → KEY_READY
├── decrypt(keyID, iv, buffer, subSamples, caps) → clear data
└── States: KEY_INIT → KEY_PENDING → KEY_READY → KEY_ERROR → KEY_CLOSED

DrmHelper hierarchy (drm/helper/)
├── DrmHelperEngine::getInstance().createHelper(drmInfo) — factory
├── WidevineDrmHelper — PSID: edef8ba9-79d6-4ace-a3c8-27dcd51d21ed
├── PlayReadyHelper — PSID: 9a04f079-9840-4286-ab92-e65be0885f95
├── ClearKeyHelper — PSID: 1077efec-c0b2-4d02-ace3-3c1e52e2fb4b
└── VerimatrixHelper — PSID: 9a27dd82-fde2-4725-8cbc-4234aa06ec09

OCDM Adapters (drm/ocdm/)
├── OcdmBasicSessionAdapter — Non-GStreamer decrypt
└── OcdmGstSessionAdapter — In-pipeline GStreamer decrypt

GStreamer Decryptors (gst-plugins/drm/gst/)
├── gstcdmidecryptor (base, extends GstBaseTransform)
├── Per buffer: GstProtectionMeta → GetSession(KID) → decrypt()
└── Properties: mDRMSessionManager (void*), mEncrypt (gboolean)
```

### Key Data Flows

```
Flow 1: DASH License Acquisition
MPD Collector → detects ContentProtection → AampDRMLicPreFetcher.Queue()
→ PreFetch thread → DrmInterface → DrmSessionManager.CreateDrmSession()
→ DrmHelperEngine.createHelper() → DrmSession.generateKeyRequest()
→ ContentSecurityManager.AcquireLicense() → License Server (HTTPS POST)
→ DrmSession.processDRMKey() → KEY_READY

Flow 2: Per-Buffer Decryption (DASH/fMP4)
GStreamer pipeline → encrypted buffer arrives at decryptor element
→ gstcdmidecryptor.transform_ip() → DrmSessionManager.GetSession(KID)
→ DrmSession.decrypt(KID, IV, buffer, subsamples)
→ OcdmGstSessionAdapter → opencdm_gstreamer_session_decrypt()
→ Clear buffer continues downstream

Flow 3: HLS AES-128
HLS Collector → detects #EXT-X-KEY → DrmInterface.GetAccessKey()
→ curl GET key URI → AES-128-CBC decrypt in-collector
→ Clear data sent to pipeline (no GStreamer decryptor needed)

Flow 4: HLS SAMPLE-AES
HLS Collector → detects SAMPLE-AES → DrmInterface.getHlsDrmSession()
→ HlsOcdmBridge created → OCDM session for SAMPLE-AES
→ Decryption in collector before pipeline injection
```

## Verification Checklist

### License Acquisition Flow
- [ ] Is DRM type correctly detected from manifest (PSSH box / ContentProtection / #EXT-X-KEY)?
- [ ] Is the correct DrmHelper created by factory (check PSID matching)?
- [ ] Is challenge generated with correct initData format?
- [ ] Are custom HTTP headers included in license request?
- [ ] Is license response correctly processed (processDRMKey)?
- [ ] Is session state correctly transitioned to KEY_READY?
- [ ] Are retry semantics correct (MAX_LICENSE_REQUEST_ATTEMPTS=2)?

### Key Rotation
- [ ] Is new KID detected in subsequent segments?
- [ ] Is new session created (or existing one reused if same KID)?
- [ ] Is old session cleaned up after rotation?
- [ ] Does pipeline handle session switch without glitch?

### Error Handling
- [ ] HDCP_COMPLIANCE_CHECK_FAILURE (4327) — correctly propagated?
- [ ] HDCP_OUTPUT_PROTECTION_FAILURE (4427) — correctly propagated?
- [ ] License server timeout — retry or fail with correct error code?
- [ ] Invalid license response — session moves to KEY_ERROR?
- [ ] Network failure during license fetch — retry semantics correct?

### Session Lifecycle
- [ ] Sessions created on ContentProtection detection (not on first buffer)
- [ ] Sessions destroyed on Stop/channel-change/TearDownStream
- [ ] No session leak on repeated Tune without Stop
- [ ] ContentSecurityManagerSession cleaned up per-playback

## Reference Diagrams
- `docs/aamp-core-sequence-diagrams/06-drm-session-manager.md`
- `middleware/docs/sequence-diagrams/04-drm.md`
- `middleware/docs/sequence-diagrams/05-externals.md`
- `AAMP-MIDDLEWARE-E2E-ARCHITECTURE.md` (Section 7: DRM License Acquisition)
101 changes: 101 additions & 0 deletions .github/prompts/middleware-compliance-review.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
agent: 'agent'
description: 'Review middleware code changes for compliance with architecture patterns, coding standards, and verified sequence diagrams.'
---

You are a middleware compliance review agent for the AAMP middleware layer (`middleware/`).

## Architecture Context (Verified from Source)

### Key Components

```
InterfacePlayerRDK (InterfacePlayerRDK.cpp/h, ~5200 lines)
├── GStreamer pipeline lifecycle (Create, Configure, SetupStream, TearDown)
├── Buffer injection via gst_app_src_push_buffer (zero-copy with shared_ptr aliasing)
├── Bus message/sync handlers for state changes, errors, EOS
├── DRM decryptor property setting (mDRMSessionManager, mEncrypt)
└── SocInterface calls for platform-specific behavior

PlayerScheduler (PlayerScheduler.cpp/h)
├── Single worker thread with condition variable
├── ScheduleTask(id, function) → async execution
└── Used for callbacks back to AAMP (IdleCallbackOnFirstFrame, etc.)

GstHandlerControl (GstHandlerControl.cpp/h)
├── RAII callback safety during teardown
├── enable() / disable() / waitForDone()
└── Prevents use-after-free in GStreamer callbacks

SocInterface (vendor/SocInterface.h)
├── Factory: CreateSocInterface(isRialto)
├── 10 pure virtual methods (SetPlaybackFlags, SetPlaybackRate, etc.)
├── Platforms: Broadcom, Realtek, MediaTek, Amlogic, Default
└── Called by InterfacePlayerRDK at pipeline setup, bus_sync, bus_message, flush

DrmSessionManager (drm/DrmSessionManager.cpp/h)
├── Manages DrmSession instances keyed by KID
├── Uses ContentSecurityManager for license acquisition
├── Called by GStreamer decryptor plugins via void* property
└── States: KEY_INIT → KEY_PENDING → KEY_READY → KEY_ERROR → KEY_CLOSED
```

### Coding Standards

- C++17 with `-Werror=format -Wno-multichar`
- RAII for all resources (GstHandlerControl pattern for callback safety)
- `pthread_mutex_t` for GStreamer thread contexts, `std::mutex` for C++ contexts
- Zero-copy: `shared_ptr` aliasing + `gst_buffer_new_wrapped_full`
- No raw `new`/`delete` — smart pointers only
- `MW_LOG_MIL/MW_LOG_WARN/MW_LOG_ERR` for logging
- Defensive GStreamer coding: NULL-check every pointer from GStreamer APIs
- GStreamer ref-counting: `gst_object_ref()` when storing, `g_clear_object()` on teardown

## Compliance Review Process

### Step 1: Context Gathering
- Read the FULL file being modified (not just the diff)
- Read the relevant sequence diagram from `middleware/docs/sequence-diagrams/`
- Identify which component is affected (IRDK, DRM, SoC, Externals, GstPlugin)

### Step 2: Architecture Alignment
- Does the change follow the verified class hierarchy?
- Are threading assumptions correct (which thread calls this code)?
- Is the change in the right layer? (no platform code in generic, no generic code in vendor)
- Does it respect the singleton patterns (ContentSecurityManager, DrmHelperEngine)?

### Step 3: Coding Standards Check
- [ ] RAII used for all resource management
- [ ] No raw new/delete
- [ ] GStreamer pointers NULL-checked before use
- [ ] GStreamer ref-counting correct (ref on store, unref on teardown)
- [ ] Logging at appropriate levels (MIL for normal, WARN for recoverable, ERR for failures)
- [ ] Input validation on all public/virtual methods
- [ ] Error paths provide fallback behavior, not just early return

### Step 4: Backward Compatibility
- [ ] No existing API signature changes without deprecation path
- [ ] Virtual method overrides maintain base class contract
- [ ] GStreamer element properties unchanged (names, types)
- [ ] Config key names unchanged
- [ ] Error codes/enums only extended, never modified

### Step 5: Test Coverage
- [ ] Unit test added/updated in `middleware/test/utests/tests/`
- [ ] Mock boundaries are at OCDM/Thunder/GStreamer (not internal logic)
- [ ] Edge cases covered (NULL inputs, timeout, thread races)

## Reference Diagrams
- `middleware/docs/sequence-diagrams/01-root-level-middleware.md` — InterfacePlayerRDK lifecycle
- `middleware/docs/sequence-diagrams/04-drm.md` — DRM session management
- `middleware/docs/sequence-diagrams/05-externals.md` — Thunder/CSM/RFC
- `middleware/docs/sequence-diagrams/06-gst-plugins.md` — Decryptor and subtitle plugins
- `middleware/docs/sequence-diagrams/09-vendor-soc.md` — SocInterface implementations

## Output Format

Produce a compliance report with:
1. **PASS/FAIL** per checklist item
2. **Findings** — specific code locations that violate standards
3. **Recommendations** — concrete fix with code snippet
4. **Risk Assessment** — HIGH/MEDIUM/LOW impact if shipped as-is
Loading