[FFmpeg-cvslog] r25796 - trunk/libavcodec/pgssubdec.c

reimar subversion
Mon Nov 22 21:35:08 CET 2010


Author: reimar
Date: Mon Nov 22 21:35:07 2010
New Revision: 25796

Log:
Support PGS subtitles with RLE data split over mutiple packets.
Patch by Mark Goodman [mark goodman gmail com] with some modifications by me.

Modified:
   trunk/libavcodec/pgssubdec.c

Modified: trunk/libavcodec/pgssubdec.c
==============================================================================
--- trunk/libavcodec/pgssubdec.c	Mon Nov 22 08:32:27 2010	(r25795)
+++ trunk/libavcodec/pgssubdec.c	Mon Nov 22 21:35:07 2010	(r25796)
@@ -54,6 +54,7 @@ typedef struct PGSSubPicture {
     int          h;
     uint8_t      *rle;
     unsigned int rle_buffer_size, rle_data_len;
+    unsigned int rle_remaining_len;
 } PGSSubPicture;
 
 typedef struct PGSSubContext {
@@ -159,6 +160,10 @@ static int parse_picture_segment(AVCodec
     uint8_t sequence_desc;
     unsigned int rle_bitmap_len, width, height;
 
+    if (buf_size <= 4)
+        return -1;
+    buf_size -= 4;
+
     /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
     buf += 3;
 
@@ -166,20 +171,22 @@ static int parse_picture_segment(AVCodec
     sequence_desc = bytestream_get_byte(&buf);
 
     if (!(sequence_desc & 0x80)) {
-        av_log(avctx, AV_LOG_ERROR, "Decoder does not support object data over multiple packets.\n");
-        return -1;
-    }
+        /* Additional RLE data */
+        if (buf_size > ctx->picture.rle_remaining_len)
+            return -1;
 
-    /* Decode rle bitmap length */
-    rle_bitmap_len = bytestream_get_be24(&buf);
+        memcpy(ctx->picture.rle + ctx->picture.rle_data_len, buf, buf_size);
+        ctx->picture.rle_data_len += buf_size;
 
-    /* Check to ensure we have enough data for rle_bitmap_length if just a single packet */
-    if (rle_bitmap_len > buf_size - 7) {
-        av_log(avctx, AV_LOG_ERROR, "Not enough RLE data for specified length of %d.\n", rle_bitmap_len);
-        return -1;
+        return 0;
     }
 
-    ctx->picture.rle_data_len = rle_bitmap_len;
+    if (buf_size <= 7)
+        return -1;
+    buf_size -= 7;
+
+    /* Decode rle bitmap length, stored size includes width/height data */
+    rle_bitmap_len = bytestream_get_be24(&buf) - 2*2;
 
     /* Get bitmap dimensions from data */
     width  = bytestream_get_be16(&buf);
@@ -199,7 +206,9 @@ static int parse_picture_segment(AVCodec
     if (!ctx->picture.rle)
         return -1;
 
-    memcpy(ctx->picture.rle, buf, rle_bitmap_len);
+    memcpy(ctx->picture.rle, buf, buf_size);
+    ctx->picture.rle_data_len = buf_size;
+    ctx->picture.rle_remaining_len = rle_bitmap_len - buf_size;
 
     return 0;
 }
@@ -364,10 +373,13 @@ static int display_end_segment(AVCodecCo
     /* Process bitmap */
     sub->rects[0]->pict.linesize[0] = ctx->picture.w;
 
-    if (ctx->picture.rle)
+    if (ctx->picture.rle) {
+        if (ctx->picture.rle_remaining_len)
+            av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n",
+                   ctx->picture.rle_data_len, ctx->picture.rle_remaining_len);
         if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0)
             return 0;
-
+    }
     /* Allocate memory for colors */
     sub->rects[0]->nb_colors    = 256;
     sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);



More information about the ffmpeg-cvslog mailing list