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