Skip to content
Snippets Groups Projects
Commit 83cd9112 authored by Mark Goodman's avatar Mark Goodman Committed by Reimar Döffinger
Browse files

Support PGS subtitles with RLE data split over mutiple packets.

Patch by Mark Goodman [mark goodman gmail com] with some modifications by me.

Originally committed as revision 25796 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent fb3d8c23
No related branches found
No related tags found
No related merge requests found
......@@ -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(AVCodecContext *avctx,
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(AVCodecContext *avctx,
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(AVCodecContext *avctx,
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(AVCodecContext *avctx, void *data,
/* 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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment