Commit db4fac64 authored by Michael Niedermayer's avatar Michael Niedermayer

Change AVSubtitle.rects to an array of pointers so ABI does not break

when the size of AVSubtitleRect changes.

Originally committed as revision 16412 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 7cf9c6ae
......@@ -1401,8 +1401,9 @@ static int output_packet(AVInputStream *ist, int ist_index,
if (subtitle_to_free) {
if (subtitle_to_free->rects != NULL) {
for (i = 0; i < subtitle_to_free->num_rects; i++) {
av_free(subtitle_to_free->rects[i].bitmap);
av_free(subtitle_to_free->rects[i].rgba_palette);
av_freep(&subtitle_to_free->rects[i]->bitmap);
av_freep(&subtitle_to_free->rects[i]->rgba_palette);
av_freep(&subtitle_to_free->rects[i]);
}
av_freep(&subtitle_to_free->rects);
}
......
......@@ -636,8 +636,9 @@ static void free_subpicture(SubPicture *sp)
for (i = 0; i < sp->sub.num_rects; i++)
{
av_free(sp->sub.rects[i].bitmap);
av_free(sp->sub.rects[i].rgba_palette);
av_freep(&sp->sub.rects[i]->bitmap);
av_freep(&sp->sub.rects[i]->rgba_palette);
av_freep(&sp->sub.rects[i]);
}
av_free(sp->sub.rects);
......@@ -721,7 +722,7 @@ static void video_image_display(VideoState *is)
pict.linesize[2] = vp->bmp->pitches[1];
for (i = 0; i < sp->sub.num_rects; i++)
blend_subrect(&pict, &sp->sub.rects[i],
blend_subrect(&pict, sp->sub.rects[i],
vp->bmp->w, vp->bmp->h);
SDL_UnlockYUVOverlay (vp->bmp);
......@@ -1435,13 +1436,13 @@ static int subtitle_thread(void *arg)
for (i = 0; i < sp->sub.num_rects; i++)
{
for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
{
RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
RGBA_IN(r, g, b, a, sp->sub.rects[i]->rgba_palette + j);
y = RGB_TO_Y_CCIR(r, g, b);
u = RGB_TO_U_CCIR(r, g, b, 0);
v = RGB_TO_V_CCIR(r, g, b, 0);
YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
YUVA_OUT(sp->sub.rects[i]->rgba_palette + j, y, u, v, a);
}
}
......
......@@ -2409,7 +2409,7 @@ typedef struct AVSubtitle {
uint32_t start_display_time; /* relative to packet pts, in ms */
uint32_t end_display_time; /* relative to packet pts, in ms */
uint32_t num_rects;
AVSubtitleRect *rects;
AVSubtitleRect **rects;
} AVSubtitle;
......
......@@ -228,8 +228,8 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
for (region_id = 0; region_id < h->num_rects; region_id++) {
*q++ = region_id;
*q++ = 0xff; /* reserved */
bytestream_put_be16(&q, h->rects[region_id].x); /* left pos */
bytestream_put_be16(&q, h->rects[region_id].y); /* top pos */
bytestream_put_be16(&q, h->rects[region_id]->x); /* left pos */
bytestream_put_be16(&q, h->rects[region_id]->y); /* top pos */
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
......@@ -239,10 +239,10 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
/* CLUT segment */
if (h->rects[clut_id].nb_colors <= 4) {
if (h->rects[clut_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[clut_id].nb_colors <= 16) {
} else if (h->rects[clut_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
......@@ -257,15 +257,15 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
*q++ = clut_id;
*q++ = (0 << 4) | 0xf; /* version = 0 */
for(i = 0; i < h->rects[clut_id].nb_colors; i++) {
for(i = 0; i < h->rects[clut_id]->nb_colors; i++) {
*q++ = i; /* clut_entry_id */
*q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
{
int a, r, g, b;
a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff;
r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff;
g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff;
b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff;
a = (h->rects[clut_id]->rgba_palette[i] >> 24) & 0xff;
r = (h->rects[clut_id]->rgba_palette[i] >> 16) & 0xff;
g = (h->rects[clut_id]->rgba_palette[i] >> 8) & 0xff;
b = (h->rects[clut_id]->rgba_palette[i] >> 0) & 0xff;
*q++ = RGB_TO_Y_CCIR(r, g, b);
*q++ = RGB_TO_V_CCIR(r, g, b, 0);
......@@ -282,10 +282,10 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
/* region composition segment */
if (h->rects[region_id].nb_colors <= 4) {
if (h->rects[region_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[region_id].nb_colors <= 16) {
} else if (h->rects[region_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
......@@ -299,8 +299,8 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
q += 2; /* segment length */
*q++ = region_id;
*q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
bytestream_put_be16(&q, h->rects[region_id].w); /* region width */
bytestream_put_be16(&q, h->rects[region_id].h); /* region height */
bytestream_put_be16(&q, h->rects[region_id]->w); /* region width */
bytestream_put_be16(&q, h->rects[region_id]->h); /* region height */
*q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
*q++ = region_id; /* clut_id == region_id */
*q++ = 0; /* 8 bit fill colors */
......@@ -322,10 +322,10 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
for (object_id = 0; object_id < h->num_rects; object_id++) {
/* Object Data segment */
if (h->rects[object_id].nb_colors <= 4) {
if (h->rects[object_id]->nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[object_id].nb_colors <= 16) {
} else if (h->rects[object_id]->nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
......@@ -358,12 +358,12 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s,
dvb_encode_rle = dvb_encode_rle4;
top_ptr = q;
dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2,
h->rects[object_id].w, h->rects[object_id].h >> 1);
dvb_encode_rle(&q, h->rects[object_id]->bitmap, h->rects[object_id]->w * 2,
h->rects[object_id]->w, h->rects[object_id]->h >> 1);
bottom_ptr = q;
dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
h->rects[object_id].w * 2, h->rects[object_id].w,
h->rects[object_id].h >> 1);
dvb_encode_rle(&q, h->rects[object_id]->bitmap + h->rects[object_id]->w,
h->rects[object_id]->w * 2, h->rects[object_id]->w,
h->rects[object_id]->h >> 1);
bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
......
......@@ -1285,14 +1285,17 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
sub->num_rects = ctx->display_list_size;
if (sub->num_rects > 0)
sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects);
if (sub->num_rects > 0){
sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects);
for(i=0; i<sub->num_rects; i++)
sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
}
i = 0;
for (display = ctx->display_list; display; display = display->next) {
region = get_region(ctx, display->region_id);
rect = &sub->rects[i];
rect = sub->rects[i];
if (!region)
continue;
......
......@@ -108,10 +108,10 @@ static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
cmap[i] = 0;
}
for (object_id = 0; object_id < rects; object_id++)
for (i=0; i<h->rects[object_id].w*h->rects[object_id].h; ++i) {
color = h->rects[object_id].bitmap[i];
for (i=0; i<h->rects[object_id]->w*h->rects[object_id]->h; ++i) {
color = h->rects[object_id]->bitmap[i];
// only count non-transparent pixels
alpha = h->rects[object_id].rgba_palette[color] >> 24;
alpha = h->rects[object_id]->rgba_palette[color] >> 24;
hist[color] += alpha;
}
for (color=3;; --color) {
......@@ -138,19 +138,19 @@ static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
for (object_id = 0; object_id < rects; object_id++) {
offset1[object_id] = q - outbuf;
// worst case memory requirement: 1 nibble per pixel..
if ((q - outbuf) + h->rects[object_id].w*h->rects[object_id].h/2
if ((q - outbuf) + h->rects[object_id]->w*h->rects[object_id]->h/2
+ 17*rects + 21 > outbuf_size) {
av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
return -1;
}
dvd_encode_rle(&q, h->rects[object_id].bitmap,
h->rects[object_id].w*2,
h->rects[object_id].w, h->rects[object_id].h >> 1,
dvd_encode_rle(&q, h->rects[object_id]->bitmap,
h->rects[object_id]->w*2,
h->rects[object_id]->w, h->rects[object_id]->h >> 1,
cmap);
offset2[object_id] = q - outbuf;
dvd_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
h->rects[object_id].w*2,
h->rects[object_id].w, h->rects[object_id].h >> 1,
dvd_encode_rle(&q, h->rects[object_id]->bitmap + h->rects[object_id]->w,
h->rects[object_id]->w*2,
h->rects[object_id]->w, h->rects[object_id]->h >> 1,
cmap);
}
......@@ -170,17 +170,17 @@ static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
// XXX not sure if more than one rect can really be encoded..
// 12 bytes per rect
for (object_id = 0; object_id < rects; object_id++) {
int x2 = h->rects[object_id].x + h->rects[object_id].w - 1;
int y2 = h->rects[object_id].y + h->rects[object_id].h - 1;
int x2 = h->rects[object_id]->x + h->rects[object_id]->w - 1;
int y2 = h->rects[object_id]->y + h->rects[object_id]->h - 1;
*q++ = 0x05;
// x1 x2 -> 6 nibbles
*q++ = h->rects[object_id].x >> 4;
*q++ = (h->rects[object_id].x << 4) | ((x2 >> 8) & 0xf);
*q++ = h->rects[object_id]->x >> 4;
*q++ = (h->rects[object_id]->x << 4) | ((x2 >> 8) & 0xf);
*q++ = x2;
// y1 y2 -> 6 nibbles
*q++ = h->rects[object_id].y >> 4;
*q++ = (h->rects[object_id].y << 4) | ((y2 >> 8) & 0xf);
*q++ = h->rects[object_id]->y >> 4;
*q++ = (h->rects[object_id]->y << 4) | ((y2 >> 8) & 0xf);
*q++ = y2;
*q++ = 0x06;
......
......@@ -80,31 +80,32 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
// allocate sub and set values
if (!sub->rects) {
sub->rects = av_mallocz(sizeof(AVSubtitleRect));
sub->rects = av_mallocz(sizeof(*sub->rects));
sub->rects[0] = av_mallocz(sizeof(*sub->rects[0]));
sub->num_rects = 1;
}
av_freep(&sub->rects[0].bitmap);
sub->rects[0].x = x; sub->rects[0].y = y;
sub->rects[0].w = w; sub->rects[0].h = h;
sub->rects[0].linesize = w;
sub->rects[0].bitmap = av_malloc(w * h);
sub->rects[0].nb_colors = 4;
sub->rects[0].rgba_palette = av_malloc(sub->rects[0].nb_colors * 4);
av_freep(&sub->rects[0]->bitmap);
sub->rects[0]->x = x; sub->rects[0]->y = y;
sub->rects[0]->w = w; sub->rects[0]->h = h;
sub->rects[0]->linesize = w;
sub->rects[0]->bitmap = av_malloc(w * h);
sub->rects[0]->nb_colors = 4;
sub->rects[0]->rgba_palette = av_malloc(sub->rects[0]->nb_colors * 4);
// read palette
for (i = 0; i < sub->rects[0].nb_colors; i++)
sub->rects[0].rgba_palette[i] = bytestream_get_be24(&buf);
for (i = 0; i < sub->rects[0]->nb_colors; i++)
sub->rects[0]->rgba_palette[i] = bytestream_get_be24(&buf);
// make all except background (first entry) non-transparent
for (i = 1; i < sub->rects[0].nb_colors; i++)
sub->rects[0].rgba_palette[i] |= 0xff000000;
for (i = 1; i < sub->rects[0]->nb_colors; i++)
sub->rects[0]->rgba_palette[i] |= 0xff000000;
// process RLE-compressed data
rlelen = FFMIN(rlelen, buf_end - buf);
init_get_bits(&gb, buf, rlelen * 8);
bitmap = sub->rects[0].bitmap;
bitmap = sub->rects[0]->bitmap;
for (y = 0; y < h; y++) {
// interlaced: do odd lines
if (y == (h + 1) / 2) bitmap = sub->rects[0].bitmap + w;
if (y == (h + 1) / 2) bitmap = sub->rects[0]->bitmap + w;
for (x = 0; x < w; ) {
int log2 = ff_log2_tab[show_bits(&gb, 8)];
int run = get_bits(&gb, 14 - 4 * (log2 >> 1));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment