From 049170a814ea3f5e80d401e73e8c4477ecedde00 Mon Sep 17 00:00:00 2001 From: jstebbins Date: Fri, 13 Jun 2014 20:37:56 +0000 Subject: decpgssub: partial fix for "multi-object" PGS subs We were packaging multiple subtitle packets with the same pts and passing down to rendersub which would then throw away all but the last sub with a given pts. So put all AVSubtitleRects into the same hb_buffer_t. A patch to libav is also required to fix the multi-object problem. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6211 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- libhb/decpgssub.c | 74 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 24 deletions(-) (limited to 'libhb/decpgssub.c') diff --git a/libhb/decpgssub.c b/libhb/decpgssub.c index 3df1cc439..89e3d7565 100644 --- a/libhb/decpgssub.c +++ b/libhb/decpgssub.c @@ -386,28 +386,55 @@ static int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, { if (!clear_subtitle) { - unsigned ii; + unsigned ii, x0, y0, x1, y1, w, h; + + x0 = subtitle.rects[0]->x; + y0 = subtitle.rects[0]->y; + x1 = subtitle.rects[0]->x + subtitle.rects[0]->w; + y1 = subtitle.rects[0]->y + subtitle.rects[0]->h; + + // First, find total bounding rectangle + for (ii = 1; ii < subtitle.num_rects; ii++) + { + if (subtitle.rects[ii]->x < x0) + x0 = subtitle.rects[ii]->x; + if (subtitle.rects[ii]->y < y0) + y0 = subtitle.rects[ii]->y; + if (subtitle.rects[ii]->x + subtitle.rects[ii]->w > x1) + x1 = subtitle.rects[ii]->x + subtitle.rects[ii]->w; + if (subtitle.rects[ii]->y + subtitle.rects[ii]->h > y1) + y1 = subtitle.rects[ii]->y + subtitle.rects[ii]->h; + } + w = x1 - x0; + h = y1 - y0; + + out = hb_frame_buffer_init(AV_PIX_FMT_YUVA420P, w, h); + memset(out->data, 0, out->size); + + out->s.frametype = HB_FRAME_SUBTITLE; + out->s.id = in->s.id; + out->sequence = in->sequence; + out->s.start = pts; + out->s.stop = AV_NOPTS_VALUE; + out->s.renderOffset = AV_NOPTS_VALUE; + out->f.x = x0; + out->f.y = y0; for (ii = 0; ii < subtitle.num_rects; ii++) { AVSubtitleRect *rect = subtitle.rects[ii]; - out = hb_frame_buffer_init(AV_PIX_FMT_YUVA420P, - rect->w, rect->h); - - out->s.frametype = HB_FRAME_SUBTITLE; - out->s.id = in->s.id; - out->sequence = in->sequence; - out->s.start = pts; - out->s.stop = AV_NOPTS_VALUE; - out->s.renderOffset = AV_NOPTS_VALUE; - out->f.x = rect->x; - out->f.y = rect->y; - + int off_x = rect->x - x0; + int off_y = rect->y - y0; uint8_t *lum = out->plane[0].data; uint8_t *chromaU = out->plane[1].data; uint8_t *chromaV = out->plane[2].data; uint8_t *alpha = out->plane[3].data; + lum += off_y * out->plane[0].stride + off_x; + alpha += off_y * out->plane[3].stride + off_x; + chromaU += (off_y >> 1) * out->plane[1].stride + (off_x >> 1); + chromaV += (off_y >> 1) * out->plane[2].stride + (off_x >> 1); + int xx, yy; for (yy = 0; yy < rect->h; yy++) { @@ -438,18 +465,17 @@ static int decsubWork( hb_work_object_t * w, hb_buffer_t ** buf_in, } alpha += out->plane[3].stride; } - - if ( pv->list_buffer == NULL ) - { - pv->list_buffer = pv->last_buffer = out; - } - else - { - pv->last_buffer->next = out; - pv->last_buffer = out; - } - out = NULL; } + if ( pv->list_buffer == NULL ) + { + pv->list_buffer = pv->last_buffer = out; + } + else + { + pv->last_buffer->next = out; + pv->last_buffer = out; + } + out = NULL; } else { -- cgit v1.2.3