This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 1c804b349eb36b96b4d337af64f9da9249f49533
Author:     James Almer <[email protected]>
AuthorDate: Mon Dec 15 19:13:02 2025 -0300
Commit:     James Almer <[email protected]>
CommitDate: Tue Dec 16 10:38:56 2025 -0300

    avcodec/jpegxs_parser: fix bitstream assembly logic
    
    JPEG-XS streams can have the bytes corresponding to certain markers as part 
of
    slice data, and no considerations were made for it, so we need to add checks
    for false positives.
    
    This fixes assembling several samples.
    
    Signed-off-by: James Almer <[email protected]>
---
 libavcodec/jpegxs_parser.c | 66 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 55 insertions(+), 11 deletions(-)

diff --git a/libavcodec/jpegxs_parser.c b/libavcodec/jpegxs_parser.c
index a6a3d1fcce..a9750b0a02 100644
--- a/libavcodec/jpegxs_parser.c
+++ b/libavcodec/jpegxs_parser.c
@@ -16,19 +16,28 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/mem.h"
+
 #include "bytestream.h"
 #include "get_bits.h"
 #include "jpegxs.h"
 #include "parser.h"
 #include "parser_internal.h"
 
+typedef struct JPEGXSParseContext {
+    ParseContext pc;
+
+    int eoc_found;
+} JPEGXSParseContext;
+
 /**
  * Find the end of the current frame in the bitstream.
  * @return the position of the first byte of the next frame, or -1
  */
-static int jpegxs_find_frame_end(ParseContext *pc, const uint8_t *buf,
+static int jpegxs_find_frame_end(JPEGXSParseContext *jpegxs, const uint8_t 
*buf,
                                  int buf_size)
 {
+    ParseContext *pc = &jpegxs->pc;
     int pic_found, i = 0;
     uint32_t state;
 
@@ -46,15 +55,41 @@ static int jpegxs_find_frame_end(ParseContext *pc, const 
uint8_t *buf,
         }
     }
 
-    if (pic_found) {
-        if (buf_size == 0)
-            return 0;
+    if (buf_size == 0) {
+        if (jpegxs->eoc_found) {
+            pc->frame_start_found = jpegxs->eoc_found = 0;
+            pc->state = -1;
+        }
+        return 0;
+    }
+
+    while (pic_found && i < buf_size) {
+        if (jpegxs->eoc_found) {
+            for(; i < buf_size; i++) {
+                state = (state << 8) | buf[i];
+                if ((state >> 16) == JPEGXS_MARKER_EOC) {
+                    if ((uint16_t)state == JPEGXS_MARKER_SOC) {
+                        // New image
+                        pc->frame_start_found = jpegxs->eoc_found = 0;
+                        pc->state = -1;
+                        return i - 1;
+                    } else {
+                        // False positive
+                        i++;
+                        jpegxs->eoc_found = 0;
+                        break;
+                    }
+                }
+            }
+        }
+
         for(; i < buf_size; i++) {
             state = (state << 8) | buf[i];
             if ((uint16_t)state == JPEGXS_MARKER_EOC) {
-                pc->frame_start_found = 0;
-                pc->state = -1;
-                return i + 1;
+                // EOC candidate
+                i++;
+                jpegxs->eoc_found = 1;
+                break;
             }
         }
     }
@@ -181,10 +216,11 @@ static int jpegxsvideo_parse(AVCodecParserContext *s,
                              const uint8_t **poutbuf, int *poutbuf_size,
                              const uint8_t *buf, int buf_size)
 {
-    ParseContext *pc = s->priv_data;
+    JPEGXSParseContext *jpegxs = s->priv_data;
+    ParseContext *pc = &jpegxs->pc;
     int next;
 
-    next = jpegxs_find_frame_end(pc, buf, buf_size);
+    next = jpegxs_find_frame_end(jpegxs, buf, buf_size);
 
     if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
         *poutbuf = NULL;
@@ -199,9 +235,17 @@ static int jpegxsvideo_parse(AVCodecParserContext *s,
     return next;
 }
 
+static av_cold void jpegxsparse_close(AVCodecParserContext *s)
+{
+    JPEGXSParseContext *jpegxs = s->priv_data;
+    ParseContext *pc = &jpegxs->pc;
+
+    av_freep(&pc->buffer);
+}
+
 const FFCodecParser ff_jpegxs_parser = {
     PARSER_CODEC_LIST(AV_CODEC_ID_JPEGXS),
-    .priv_data_size = sizeof(ParseContext),
+    .priv_data_size = sizeof(JPEGXSParseContext),
     .parse          = jpegxsvideo_parse,
-    .close          = ff_parse_close,
+    .close          = jpegxsparse_close,
 };

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to