libavcodec/jpeg2000_parser: Fix skipping of JP2 info markers by correctly
reading marker size.

This fixes playback of some JPEG2000 files that fail with a frame not found
error.

When reading the JP2 info markers, the parser can be triggered into
incorrectly calculating the number of bytes to skip of the next tag. This
is error is buffer data dependant.

This patch corrects this testing if the next marker is a info marker, and
correcting the number of skipped bytes if it is.

Please note that this is patch 2/2

PATCH 1/2 libavcodec/jpeg2000_parser: Fix parsing of tile-part  header, and
frames where the end of frame marker is at the end of the buffer

I apologise for splitting the patches this way.

Thank you,

Shaun Simpson
From bea5f87977789ca69b3601c3388b6ca575d976cb Mon Sep 17 00:00:00 2001
From: Shaun Simpson <shauns2...@gmail.com>
Date: Wed, 21 Jul 2021 14:15:45 +0100
Subject: [PATCH 2/2] libavcodec/jpeg2000_parser: Fix skipping of JP2 info
 markers by correctly reading marker size.

Signed-off-by: Shaun Simpson <shauns2...@gmail.com>
---
 libavcodec/jpeg2000_parser.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/libavcodec/jpeg2000_parser.c b/libavcodec/jpeg2000_parser.c
index b332a067e5..e16ca2174c 100644
--- a/libavcodec/jpeg2000_parser.c
+++ b/libavcodec/jpeg2000_parser.c
@@ -81,7 +81,7 @@ static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
 {
     ParseContext *pc= &m->pc;
     int i;
-    uint32_t state;
+    uint32_t state, next_state;
     uint64_t state64;
     state= pc->state;
     state64 = pc->state64;
@@ -142,7 +142,17 @@ static int find_frame_end(JPEG2000ParserContext *m, const uint8_t *buf, int buf_
         } else if (m->in_codestream && (state & 0xFFFF) == 0xFF90) { // Are we in tile part header?
             m->read_tp = 8;
         } else if (pc->frame_start_found && info_marker((state & 0xFFFF0000)>>16) && m->in_codestream) {
-            m->skip_bytes = (state & 0xFFFF) - 2;
+            // Calculate number of bytes to skip to get to end of the next marker.
+            m->skip_bytes = (state & 0xFFFF)-1;
+
+            // If the next marker is an info marker, skip to the end of of the marker length.
+            if (i + m->skip_bytes + 1 < buf_size) {
+                next_state = (buf[i + m->skip_bytes] << 8) | buf[i + m->skip_bytes + 1];
+                if (info_marker(next_state)) {
+                    // Skip an additional 2 bytes to get to the end of the marker length.
+                    m->skip_bytes += 2;
+                }
+            }
         }
     }
 
-- 
2.30.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to