Skip to content

Latest commit

 

History

History
513 lines (425 loc) · 17.7 KB

File metadata and controls

513 lines (425 loc) · 17.7 KB

OpenIMP Implementation Status

Overview

Reverse-engineered implementation of Ingenic Media Platform (IMP) libraries based on Binary Ninja MCP decompilations of libimp.so v1.1.6 for T31 platform.

Current OEM Parity Status (2026-04-18)

Executive Summary

OpenIMP is no longer blocked on basic pipeline plumbing. The active blocker is now narrow and specific:

  • the AVPU runs
  • interrupts fire
  • frames advance
  • streams are queued and released correctly
  • periodic IDRs appear
  • but the hardware still writes no entropy-coded payload bytes after the software-prewritten H.264 headers

Current symptom on device:

  • P-frames: len=14, NALs: 9 1, nz_after_hdr=0
  • IDR frames: len=47, NALs: 9 7 8 5, nz_after_hdr=0

This means the header path is substantially closer to OEM, but the final entropy/payload-write stage is still not at parity.

Latest Log Verdict

From the latest logs.txt capture:

  • live Enc2 CL logging is working
  • repeated P-frame Enc2 submissions show stable values:
    • cmd[0x1b]=0x00070c80
    • cmd[0x1c]=0x21230904
    • cmd[0x1d]=0x00027000
    • cmd[0x1e]=0x14000007
  • P-frames still end as header-only stubs:
    • raw_end=14, annexb=14, nz_after_hdr=0
  • GOP-based periodic IDR cadence is working:
    • example: frame 200 emits NALs: 9 7 8 5
    • but the IDR is still header-only: len=47, nz_after_hdr=0

What Is Known

High confidence

  1. The old capture/refcount stall is fixed

    • frames continue advancing far past the earlier stall point
    • interrupts/completions remain live
  2. Stream lifecycle bugs are no longer the main blocker

    • completed stream buffers rotate correctly
    • the exact completed buffer is returned and released
  3. Periodic IDR scheduling now works

    • logs show scheduled refresh points and NALs: 9 7 8 5
  4. Header generation and splice bookkeeping are at least partially correct

    • P path: AUD + slice header
    • IDR path: AUD + SPS + PPS + IDR slice header
  5. The remaining failure is specifically “no payload after header”

    • nz_after_hdr=0
    • raw_end == hdr_offset
    • no nonzero bytes appear after the software-prewritten header window

Medium confidence

  1. Enc2 word structure is closer to OEM than before

    • SliceParamToCmdRegsEnc2 was decompiled and the code now uses OEM-shaped packers for cmd[0x1b], cmd[0x1c], and cmd[0x1d]
  2. cmd[0x1d] is likely no longer the main bug

    • current submitted value matches the recovered 640x360 OEM shape: 0x00027000
  3. cmd[0x1b] is probably okay for the current baseline case

    • live submitted value matches the known-good stock value: 0x00070c80

Low confidence / still unresolved

  1. All runtime slice fields feeding cmd[0x1c] are correct

    • layout is improved and the 640x360 baseline P-frame word now matches the stock/live shape, but some late OEM field producers are still inferred rather than fully recovered
  2. Post-CL register block parity is complete

  • 0x84000x8428 is much closer to OEM, but still not proven complete for active P-frame entropy submission
  1. cmd[0x1e] is not fully explained yet
  • SliceParamToCmdRegsEnc2 and GenerateAvcSliceHeader recovered the word layout and the +0xf8/+0x100 producers, but UpdateCommand still owns a late runtime producer for SliceParam+0xfc
  1. SliceParam+0x66 is likely picture-command-driven
  • AL_ApplyPictCommands copies command payload bytes at offsets 0x66 and 0x67 into encoder runtime state under picture-command flag 0x400, which is a stronger lead than the older static entropy-mode guesses

Confidence Matrix

Topic Confidence Why
Capture/refcount stall fixed High Frames advance; IRQ/completion path stays live
Stream buffer ownership/lifecycle fixed High Completed buffers rotate and release correctly
Periodic IDR cadence fixed High Logs show NALs: 9 7 8 5
Header generation/splice path mostly correct High AU headers are structured correctly for P and IDR
Failure is payload-write specific High nz_after_hdr=0 and raw_end==hdr_offset repeatedly
cmd[0x1b] parity for 640x360 baseline Medium-High Live value matches stock shape
cmd[0x1d] parity Medium-High Live value matches recovered OEM formula
cmd[0x1c] fully correct Medium-Low P-frame shape matches stock/live, but some producers remain inferred
cmd[0x1e] fully explained Low +0xf8/+0x100 are proven; +0xfc still depends on UpdateCommand
SliceParam+0x66 source identified Low-Medium AL_ApplyPictCommands points to picture-command state, but the exact state slot is still unmapped
0x84000x8428 post-CL parity complete Low-Medium Still a plausible remaining mismatch area
Working AVPU H.264 parity is close Medium The remaining failure surface is much smaller, but still blocking payload

What’s Next

Highest-signal next step

Recover the remaining runtime-produced slice fields that feed Enc2, especially the fields that ultimately land in cmd[0x1c], the picture-command state behind SliceParam+0x66, and the unresolved UpdateCommand -> SliceParam+0xfc producer behind cmd[0x1e].

Most likely OEM sources:

  • UpdateCommand
  • GenerateAvcSliceHeader
  • CmdRegsEnc1ToSliceParam
  • SliceParamToCmdRegsEnc2
  • AL_ApplyPictCommands

Second-highest-signal step

Re-check the post-CL register/config block for the active P-frame entropy path, especially around:

  • 0x84000x8428
  • header offset alignment
  • stream-part windowing
  • ordering relative to CL_PUSH=8

Success criteria

We should consider the AVPU path meaningfully unblocked when logs show:

  • nz_after_hdr > 0
  • raw_end > hdr_offset
  • P-frames longer than 14 bytes
  • IDRs longer than header-only 47 bytes
  • decoder-visible payload rather than only NALs: 9 1 or header-only 9 7 8 5

Note on the rest of this document

The remainder of CURRENT_STATUS.md is older, broader implementation history. It is still useful for module-level context, but the section above is the most accurate summary of the current OEM-parity blocker.

Build Statistics

  • Library Size: 125KB (libimp.a), 88KB (libimp.so)
  • Total Lines: 4,313 lines of implementation code
  • Last Updated: 2026-04-03
  • Build Status: ✅ Compiles cleanly with minor warnings
  • Modules: 10 modules implemented
  • Build Status: ✅ Compiles cleanly with only minor warnings

Recent Additions (2025-10-11)

DMA Allocator with Kernel Driver Integration ✅ - src/dma_alloc.c

  • Status: COMPLETE
  • Features:
    • Real kernel driver integration via /dev/mem and /dev/jz-dma
    • DMABuffer structure (0x94 bytes) with safe member access
    • IMP_Alloc/IMP_PoolAlloc/IMP_Free with actual mmap()
    • ioctl commands: IOCTL_MEM_ALLOC, IOCTL_MEM_FREE, IOCTL_MEM_GET_PHY, IOCTL_MEM_FLUSH
    • Fallback to posix_memalign() if kernel unavailable
    • Thread-safe with mutex protection
    • Physical/virtual address mapping
  • Size: ~280 lines of code

Frame Capture Thread ✅ - src/imp_framesource.c

  • Based on: Decompilation at 0x99acc
  • Status: COMPLETE
  • Features:
    • frame_capture_thread() polls kernel driver
    • ioctl VIDIOC_POLL_FRAME (0x400456bf) for frame availability
    • Gets frames from VBM pool
    • Integrated with IMP_FrameSource_EnableChn/DisableChn
    • Proper thread lifecycle (create on enable, cancel on disable)
    • Safe struct member access with memcpy()
  • Integration: Runs continuously when channel is enabled

Encoder Processing Threads ✅ - src/imp_encoder.c

  • Status: COMPLETE
  • Features:
    • encoder_thread() - Processes frames through codec
    • stream_thread() - Retrieves encoded streams
    • eventfd signaling between threads
    • AL_Codec_Encode_Process() integration
    • AL_Codec_Encode_GetStream() integration
    • Proper thread synchronization with select()
  • Integration: Threads created in IMP_Encoder_CreateChn

Observer Pattern Implementation ✅ - src/imp_system.c

  • Based on: Decompilations at 0x1a920, 0x1aa54, 0x1b388
  • Status: COMPLETE
  • Features:
    • Observer structure for module binding
    • add_observer() - Add observer to list
    • remove_observer() - Remove observer from list
    • notify_observers() - Notify all observers with frame
    • BindObserverToSubject() - Bind two modules
    • system_bind() - Internal bind implementation
    • IMP_System_RegisterModule() - Register module in global registry
  • Integration: Ready for FrameSource -> Encoder binding

Completed Implementations

1. Core Infrastructure ✅

Fifo (FIFO Queue) - src/fifo.c

  • Based on: Decompilations at 0x7af28, 0x7b254, 0x7b384
  • Status: COMPLETE
  • Features:
    • Thread-safe queue with mutex, condition variable, semaphore
    • Timeout support (infinite, no-wait, timed)
    • Abort flag for graceful shutdown
    • Proper initialization and cleanup
  • Size: 64 bytes structure, ~280 lines of code

VBM (Video Buffer Manager) - src/kernel_interface.c

  • Based on: Decompilation at 0x1efe4
  • Status: COMPLETE (core functions)
  • Features:
    • VBMCreatePool with 12+ pixel format support
    • Frame size calculation for NV12, RGB, YUV, etc.
    • Memory allocation via IMP_Alloc/IMP_PoolAlloc
    • Physical/virtual address management
    • Global frame volume tracking (30 entries)
    • VBMDestroyPool, VBMFillPool, VBMFlushFrame, VBMGetFrame, VBMReleaseFrame
  • Structures:
    • VBMPool: 0x180 + (bufcount * 0x428) bytes
    • VBMFrame: 0x428 bytes per frame
    • VBMVolume: Global array for frame tracking

AL_Codec (Encoder Codec) - src/codec.c

  • Based on: Decompilations at 0x7950c, 0x7a180, 0x790b8, etc.
  • Status: COMPLETE (core functions)
  • Features:
    • AL_Codec_Encode_Create/Destroy
    • AL_Codec_Encode_SetDefaultParam (full parameter initialization)
    • AL_Codec_Encode_GetSrcFrameCntAndSize
    • AL_Codec_Encode_GetSrcStreamCntAndSize
    • AL_Codec_Encode_Process (frame queuing)
    • AL_Codec_Encode_GetStream/ReleaseStream
    • Dual FIFO system for frames and streams
  • Structure: 0x924 bytes (AL_CodecEncode)
  • Size: ~350 lines of code

2. System Module ✅ - src/imp_system.c

  • Based on: Decompilations at 0x1b01c, 0x1b1e0, etc.
  • Status: COMPLETE
  • Features:
    • Module structure (0x148+ bytes) with exact offsets
    • g_modules[6][6] global registry at 0x108ca0
    • Observer pattern binding mechanism
    • Timestamp system with CLOCK_MONOTONIC
    • CPU ID mapping for 24 Ingenic platforms
    • IMP_System_Init/Exit
    • IMP_System_Bind/UnBind
    • IMP_System_GetVersion

3. Encoder Module ✅ - src/imp_encoder.c

  • Based on: Decompilations at 0x836e0, 0x80b40, etc.
  • Status: COMPLETE (core functions)
  • Features:
    • EncChannel structure (0x308 bytes) with exact offsets
    • g_EncChannel[9] global array
    • IMP_Encoder_CreateChn (full implementation)
    • IMP_Encoder_DestroyChn
    • IMP_Encoder_RegisterChn/UnRegisterChn
    • IMP_Encoder_StartRecvPic/StopRecvPic
    • Encoder and stream threads (basic loop)
    • 3 semaphores, 2 mutexes (one recursive)
    • Event FD creation
    • Frame buffer allocation
  • Size: ~775 lines of code

4. FrameSource Module ✅ - src/imp_framesource.c

  • Based on: Decompilations at 0x9ecf8, 0x9ed84, etc.
  • Status: COMPLETE (core functions)
  • Features:
    • FSChannel structure (0x2e8 bytes)
    • IMP_FrameSource_CreateChn/DestroyChn
    • IMP_FrameSource_SetChnAttr/GetChnAttr
    • IMP_FrameSource_EnableChn/DisableChn (with kernel driver integration)
    • IMP_FrameSource_GetFrame/ReleaseFrame
    • Device operations via /dev/framechan%d
  • Size: ~400 lines of code

5. Kernel Driver Interface ✅ - src/kernel_interface.c

  • Based on: FrameSource decompilations
  • Status: COMPLETE (core ioctls)
  • Features:
    • 6 ioctl commands:
      • 0x407056c4 (GET_FMT)
      • 0xc07056c3 (SET_FMT)
      • 0xc0145608 (SET_BUFCNT)
      • 0x800456c5 (SET_DEPTH)
      • 0x80045612 (STREAM_ON)
      • 0x80045613 (STREAM_OFF)
    • Device open with retry logic (257 retries, 10ms delay)
    • VBM implementation
  • Size: ~550 lines of code

6. Audio Module ✅ - src/imp_audio.c

  • Based on: Audio decompilations
  • Status: COMPLETE (structure and lifecycle)
  • Features:
    • AudioDevice structure (0x260 bytes)
    • AudioChannel structure (0x208 bytes)
    • IMP_AI_SetPubAttr/GetPubAttr
    • IMP_AI_Enable/Disable
    • IMP_AI_EnableChn/DisableChn
    • IMP_AI_PollingFrame/GetFrame/ReleaseFrame
  • Size: ~350 lines of code

7. OSD Module ✅ - src/imp_osd.c

  • Based on: OSD decompilations
  • Status: COMPLETE (structure and lifecycle)
  • Features:
    • OSDRegion structure (0x38 bytes)
    • Free/used region lists
    • IMP_OSD_CreateGroup/DestroyGroup
    • IMP_OSD_CreateRgn/DestroyRgn
    • IMP_OSD_RegisterRgn/UnRegisterRgn
    • IMP_OSD_SetRgnAttr/GetRgnAttr
    • IMP_OSD_ShowRgn/HideRgn
  • Size: ~400 lines of code

8. ISP Module ⚠️ - src/imp_isp.c

  • Status: STUB (basic structure only)
  • Size: ~100 lines of code

9. IVS Module ⚠️ - src/imp_ivs.c

  • Status: STUB (basic structure only)
  • Size: ~70 lines of code

What's Working

  1. Build System: Clean compilation, proper linking
  2. Thread Safety: Proper mutex/semaphore/condition variable usage
  3. Memory Management: Proper allocation/deallocation
  4. Module System: Registration, binding, lifecycle
  5. Encoder: Channel creation with full initialization
  6. FrameSource: Device operations, format control
  7. VBM: Frame buffer management
  8. Fifo: Thread-safe queuing
  9. Codec: Parameter initialization, frame/stream queuing

What Needs Work

1. Hardware Integration (HIGH PRIORITY)

  • IMP_Alloc/IMP_Free: Need actual kernel driver calls for DMA memory
  • Physical memory mapping: mmap() integration
  • VBM frame queuing: Actual buffer exchange with kernel driver
  • FrameSource capture: Real frame capture from /dev/framechan%d

2. Encoder Processing (HIGH PRIORITY)

  • Encoder thread: Actual frame encoding loop
    • Get frames from FrameSource via binding
    • Process through codec
    • Handle frame timing
  • Stream thread: Actual stream output handling
    • Get encoded streams from codec
    • Queue for IMP_Encoder_GetStream
    • Handle stream release
  • IMP_Encoder_GetStream: Full implementation (decompiled at 0x84c5c)
  • IMP_Encoder_ReleaseStream: Full implementation (decompiled at 0x85508)

3. Codec Hardware Integration (MEDIUM PRIORITY)

  • AL_Encoder_Create: Actual hardware encoder initialization
  • AL_Encoder_Process: Real encoding via hardware
  • AL_Encoder_Destroy: Hardware cleanup
  • Buffer pools: Actual DMA buffer management
  • PixMap pools: Frame buffer management

4. Module Binding (MEDIUM PRIORITY)

  • Observer notifications: Actual data flow between modules
  • Frame passing: FrameSource → Encoder data path
  • Buffer management: Shared buffer pools

5. ISP Module (LOW PRIORITY)

  • Full ISP implementation
  • Tuning daemon integration
  • Algorithm threads

6. IVS Module (LOW PRIORITY)

  • Intelligent video surveillance functions
  • Motion detection
  • Object tracking

Key Data Structures (All Exact Binary Offsets)

Module (0x148+ bytes)

  • 0x00: name[16]
  • 0x40: bind_func
  • 0x44: unbind_func
  • 0x58: observer_list
  • 0xe4: sem_e4
  • 0xf4: sem_f4
  • 0x104: thread
  • 0x108: mutex
  • 0x130: group_id

EncChannel (0x308 bytes)

  • 0x00: chn_id
  • 0x08: codec
  • 0x0c: src_frame_cnt
  • 0x10: src_frame_size
  • 0x14: frame_buffers
  • 0x18: fifo[64]
  • 0x98: attr
  • 0x1d8: mutex_1d8
  • 0x1f0: cond_1f0
  • 0x220: eventfd
  • 0x398: registered
  • 0x3ac: started
  • 0x400: recv_pic_enabled
  • 0x404: recv_pic_started
  • 0x408: sem_408
  • 0x418: sem_418
  • 0x428: sem_428
  • 0x438: mutex_438
  • 0x450: mutex_450 (recursive)
  • 0x468: thread_encoder
  • 0x46c: thread_stream

FSChannel (0x2e8 bytes)

  • 0x00: chn_id
  • 0x1c: state
  • 0x1c4: fd
  • 0x1c8: attr

AL_CodecEncode (0x924 bytes)

  • 0x000: g_pCodec
  • 0x004: codec_param[0x794]
  • 0x798: encoder
  • 0x79c: event
  • 0x7a0: callback
  • 0x7a4: callback_arg
  • 0x7a8: channel_id
  • 0x7ac: stream_buf_count
  • 0x7b0: stream_buf_size
  • 0x7f8: fifo_frames[64]
  • 0x81c: fifo_streams[64]
  • 0x840: frame_buf_count
  • 0x8dc: frame_buf_size
  • 0x918: src_fourcc
  • 0x920: metadata_type

Next Steps (Priority Order)

  1. Implement IMP_Alloc/IMP_Free with kernel driver

    • Find /dev/mem or /dev/ipu device
    • Implement mmap() for physical memory
    • Integrate with VBM
  2. Implement IMP_Encoder_GetStream/ReleaseStream

    • Based on decompilations at 0x84c5c, 0x85508
    • Stream queue management
    • Semaphore-based blocking
  3. Implement encoder/stream threads

    • Frame capture from FrameSource
    • Actual encoding loop
    • Stream output handling
  4. Test with prudynt-t

    • Validate API compatibility
    • Test actual streaming
    • Debug issues
  5. Implement remaining codec functions

    • Hardware encoder integration
    • Buffer pool management
    • Metadata handling

Testing Strategy

  1. Unit Tests: Test individual functions
  2. Integration Tests: Test module interactions
  3. prudynt-t: Real-world application testing
  4. Hardware Tests: Actual encoding on T31 device

Documentation

  • IMPLEMENTATION_PROGRESS.md: Detailed progress tracking
  • REVERSE_ENGINEERING_SUMMARY.md: Technical summary
  • BINARY_ANALYSIS.md: Binary analysis findings
  • SESSION_SUMMARY.md: Session summaries
  • CURRENT_STATUS.md: This file

Conclusion

We have successfully implemented the core infrastructure and most API functions based on actual binary decompilations. The architecture is correct, data structures match the binary exactly, and the API is fully compatible. The remaining work is primarily hardware integration and actual encoding logic.

This is a true reverse-engineered implementation, not a stub library! 🎯