Skip motion comparison when camera frame size changes - #475
Open
munzzyy wants to merge 1 commit into
Open
Conversation
processNewFrame() hands the previous frame's buffer (lastPic) to MotionDetector.detect() along with the CURRENT frame's width/height. If the camera's preview size changes between two frames, lastPic is still sized for the old resolution, so ImageCodec.N21toLuma() ends up indexing it with the new (larger) width*height and throws ArrayIndexOutOfBoundsException. Track the size lastPic was captured at and only pass it along for comparison when it matches the current frame's size. Otherwise this frame is treated the same way as the very first frame (no previous frame to compare against), which is correct since there's nothing usable to diff against anyway. Fixes guardianproject#468
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #468.
Traced the crash back past
ImageCodec.N21toLuma()andMotionDetector.detect()to where the frames actually come from:CameraViewHolder.processNewFrame().lastPicis the previous frame's raw buffer, but it gets passed todetect()along with the current frame's width/height. Most of the time that's fine because the camera preview size doesn't change between frames. But if it does change (camera restart, resolution switch, etc.),lastPicis still sized for the old resolution while width/height describe the new one.N21toLuma()then indexes the old, smaller buffer using the new, largerwidth*height, and you get the exact crash from the issue.Fix tracks the size
lastPicwas captured at and only hands it todetect()when it matches the current frame's size. When it doesn't match, this frame is treated the same as the very first frame (no previous frame to compare against yet), since there's nothing valid to diff against anyway.I didn't just clamp the loop in
N21toLuma()to the buffer length, since that would still compare frames of different resolutions pixel-by-pixel against garbage data and produce a bogus "motion detected" event. Skipping the comparison for that one frame is the correct behavior.This repo has no Android instrumentation set up in my checkout, so I couldn't run it through the app itself. I copied the exact code path (N21toLuma, the same/different-size branching) into a plain Java file outside the project and ran it standalone: confirmed the fix prevents the crash on a resolution change and leaves the normal same-size case untouched.