Repository navigation
feat: hardware MJPEG decoding through MediaCodec where available (#132, single view) - #135
Conversation
…deo/jpeg), BitmapFactory as the fallback (#132)
|
/review |
Code Review by Qodo
1.
|
| if (!hwJpegFailed && !jpegDrawn && JpegCodec.find() != null) { | ||
| int[] size = JpegAssembler.size(frame.data(), frame.length()); | ||
| if (size != null) { | ||
| try { | ||
| if (jpegCodec.decode(frame, s, size[0], size[1])) { |
There was a problem hiding this comment.
5. A surface change can disable hardware jpeg 🐞 Bug ☼ Reliability
replaceSurface() releases the JPEG codec before changing mVideoSurface, but drawJpeg() captures that surface before entering the codec's synchronized decode() method. If the view changes surface after that capture, the worker can attempt to configure against the released surface, and the resulting exception sets hwJpegFailed for the rest of the run.
Agent Prompt
## Issue description
A concurrent surface replacement can make an otherwise working hardware decoder fail permanently.
## Fix Focus Areas
- android/app/src/main/java/com/openipc/decoder/Decoder.java[1572-1580]
- android/app/src/main/java/com/openipc/decoder/Decoder.java[1611-1627]
## Recommended Fix
Coordinate surface selection and replacement with hardware decoding, or recognize a stale-surface exception and retry on the current surface without permanently setting `hwJpegFailed`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
…rs when there is none (#132)
… software, size walks the markers, no restart after stop, surface swaps not fatal, stack trace logged
|
Qodo review — all six accepted and fixed:
Device result (Aceline-1): the AG-216 declares |
Thanks for the detailed validation. The current diff addresses all six review findings, including the JPEG size parsing, bounded no-output fallback, stop/surface-generation checks, and traceback logging. The Aceline-1 result also confirms the intended behavior: when the vendor decoder cannot be created, the app falls back to software decoding while retaining hardware support for compatible devices. |
|
Device check of the final build (Aceline-1, cb04ca0): no listed JPEG decoder, the by-name attempt fails once, the app logs the fallback with the stack trace and plays |
… software, size walks the markers, no restart after stop, surface swaps not fatal, stack trace logged
feat: hardware MJPEG decoding through MediaCodec where available (#132, single view)
Part of #132 (the single-view half; MJPEG in multi-view follows).
JpegCodec: looks up a decoder forvideo/jpeg/video/mjpeg/video/x-motion-jpegonce (the AG-216 listsOMX.allwinner.video.decoder.mjpeg), creates it for the frame size (JpegAssembler.size()from SOF0) with the video surface as output, queues each whole JPEG and renders the output buffers.drawJpegtries it first; on any failure it logsHardware MJPEG decoder failed, decoding in softwareand uses the BitmapFactory path of feat: MJPEG over RTSP (RTP/JPEG, RFC 2435) in the single view (#119) #131 for the rest of the run.lockCanvas()on the hardware path, so switching to an H.264/H.265 stream needs no new surface; the JPEG decoder is released on a codec change, a surface change and when the streams stop.JpegAssembler.size().Device check: Aceline-1,
.133 /stream=2— logMJPEG decoder: OMX.allwinner.video.decoder.mjpeg/Start MJPEG decoder … 1280x720, picture, lower CPU than the software path; back to H.265 works.