summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authormplayer-svn <svn@mplayerhq.hu>2012-04-22 21:52:39 +0000
committerwm4 <wm4@nowhere>2012-08-03 03:34:38 +0200
commit0dc290269d925bd3bc7ed63a1b63edc13e8b2ab1 (patch)
tree6b26a34cbfb4b039556b38a5483a71cb9f5abef0 /sub
parent7e87c0e76a69918296161f77c0cf337650d249c1 (diff)
downloadmpv-0dc290269d925bd3bc7ed63a1b63edc13e8b2ab1.tar.bz2
mpv-0dc290269d925bd3bc7ed63a1b63edc13e8b2ab1.tar.xz
av_sub, spudec: support multiple rectangles
av_sub: support multiple rectangles. The "packet_t" structure is renamed with a prefix, because it is used a public header. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@34872 b3059339-0415-0410-9bf9-f77b7e298cf2 Author: cigaes
Diffstat (limited to 'sub')
-rw-r--r--sub/av_sub.c52
-rw-r--r--sub/spudec.c94
-rw-r--r--sub/spudec.h8
3 files changed, 113 insertions, 41 deletions
diff --git a/sub/av_sub.c b/sub/av_sub.c
index 3a9e1b4f26..56acfc63ca 100644
--- a/sub/av_sub.c
+++ b/sub/av_sub.c
@@ -32,6 +32,47 @@ void reset_avsub(struct sh_sub *sh)
}
}
+static void avsub_to_spudec(AVSubtitleRect **rects, int num_rects,
+ double pts, double endpts)
+{
+ int i, xmin = INT_MAX, ymin = INT_MAX, xmax = INT_MIN, ymax = INT_MIN;
+ struct spu_packet_t *packet;
+
+ if (num_rects == 1) {
+ spudec_set_paletted(vo_spudec,
+ rects[0]->pict.data[0],
+ rects[0]->pict.linesize[0],
+ rects[0]->pict.data[1],
+ rects[0]->x,
+ rects[0]->y,
+ rects[0]->w,
+ rects[0]->h,
+ pts,
+ endpts);
+ return;
+ }
+ for (i = 0; i < num_rects; i++) {
+ xmin = FFMIN(xmin, rects[i]->x);
+ ymin = FFMIN(ymin, rects[i]->y);
+ xmax = FFMAX(xmax, rects[i]->x + rects[i]->w);
+ ymax = FFMAX(ymax, rects[i]->y + rects[i]->h);
+ }
+ packet = spudec_packet_create(xmin, ymin, xmax - xmin, ymax - ymin);
+ if (!packet)
+ return;
+ spudec_packet_clear(packet);
+ for (i = 0; i < num_rects; i++)
+ spudec_packet_fill(packet,
+ rects[i]->pict.data[0],
+ rects[i]->pict.linesize[0],
+ rects[i]->pict.data[1],
+ rects[i]->x - xmin,
+ rects[i]->y - ymin,
+ rects[i]->w,
+ rects[i]->h);
+ spudec_packet_send(vo_spudec, packet, pts, endpts);
+}
+
/**
* Decode a subtitle packet via libavcodec.
* \return < 0 on error, > 0 if further processing is needed
@@ -96,16 +137,7 @@ int decode_avsub(struct sh_sub *sh, uint8_t *data, int size,
case SUBTITLE_BITMAP:
if (!vo_spudec)
vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0);
- spudec_set_paletted(vo_spudec,
- sub.rects[0]->pict.data[0],
- sub.rects[0]->pict.linesize[0],
- sub.rects[0]->pict.data[1],
- sub.rects[0]->x,
- sub.rects[0]->y,
- sub.rects[0]->w,
- sub.rects[0]->h,
- pts,
- endpts);
+ avsub_to_spudec(sub.rects, sub.num_rects, pts, endpts);
vo_osd_changed(OSDTYPE_SPU);
break;
default:
diff --git a/sub/spudec.c b/sub/spudec.c
index 6eabaf5723..33a5aabba1 100644
--- a/sub/spudec.c
+++ b/sub/spudec.c
@@ -60,8 +60,8 @@ int spu_alignment = -1;
float spu_gaussvar = 1.0;
extern int sub_pos;
-typedef struct packet_t packet_t;
-struct packet_t {
+typedef struct spu_packet_t packet_t;
+struct spu_packet_t {
int is_decoded;
unsigned char *packet;
int data_len;
@@ -1324,25 +1324,14 @@ void spudec_free(void *this)
}
}
-/**
- * palette must contain at least 256 32-bit entries, otherwise crashes
- * are possible
- */
-void spudec_set_paletted(void *this, const uint8_t *pal_img, int pal_stride,
- const void *palette,
- int x, int y, int w, int h,
- double pts, double endpts)
+#define MP_NOPTS_VALUE (-1LL<<63) //both int64_t and double should be able to represent this exactly
+
+packet_t *spudec_packet_create(int x, int y, int w, int h)
{
- int i;
- uint16_t g8a8_pal[256];
packet_t *packet;
- const uint32_t *pal = palette;
- spudec_handle_t *spu = this;
- uint8_t *img;
- uint8_t *aimg;
int stride = (w + 7) & ~7;
if ((unsigned)w >= 0x8000 || (unsigned)h > 0x4000)
- return;
+ return NULL;
packet = calloc(1, sizeof(packet_t));
packet->is_decoded = 1;
packet->width = w;
@@ -1352,21 +1341,47 @@ void spudec_set_paletted(void *this, const uint8_t *pal_img, int pal_stride,
packet->start_row = y;
packet->data_len = 2 * stride * h;
if (packet->data_len) { // size 0 is a special "clear" packet
- packet->packet = malloc(packet->data_len);
- img = packet->packet;
- aimg = packet->packet + stride * h;
- for (i = 0; i < 256; i++) {
- uint32_t pixel = pal[i];
- int alpha = pixel >> 24;
- int gray = (((pixel & 0x000000ff) >> 0) +
- ((pixel & 0x0000ff00) >> 7) +
- ((pixel & 0x00ff0000) >> 16)) >> 2;
- gray = FFMIN(gray, alpha);
- g8a8_pal[i] = (-alpha << 8) | gray;
- }
- pal2gray_alpha(g8a8_pal, pal_img, pal_stride,
- img, aimg, stride, w, h);
+ packet->packet = malloc(packet->data_len);
+ if (!packet->packet) {
+ free(packet);
+ packet = NULL;
+ }
+ }
+ return packet;
+}
+
+void spudec_packet_clear(packet_t *packet)
+{
+ /* clear alpha and value, as value is premultiplied */
+ memset(packet->packet, 0, packet->data_len);
+}
+
+void spudec_packet_fill(packet_t *packet,
+ const uint8_t *pal_img, int pal_stride,
+ const void *palette,
+ int x, int y, int w, int h)
+{
+ const uint32_t *pal = palette;
+ uint8_t *img = packet->packet + x + y * packet->stride;
+ uint8_t *aimg = img + packet->stride * packet->height;
+ int i;
+ uint16_t g8a8_pal[256];
+
+ for (i = 0; i < 256; i++) {
+ uint32_t pixel = pal[i];
+ int alpha = pixel >> 24;
+ int gray = (((pixel & 0x000000ff) >> 0) +
+ ((pixel & 0x0000ff00) >> 7) +
+ ((pixel & 0x00ff0000) >> 16)) >> 2;
+ gray = FFMIN(gray, alpha);
+ g8a8_pal[i] = (-alpha << 8) | gray;
}
+ pal2gray_alpha(g8a8_pal, pal_img, pal_stride,
+ img, aimg, packet->stride, w, h);
+}
+
+void spudec_packet_send(void *spu, packet_t *packet, double pts, double endpts)
+{
packet->start_pts = 0;
packet->end_pts = 0x7fffffff;
if (pts != MP_NOPTS_VALUE)
@@ -1375,3 +1390,20 @@ void spudec_set_paletted(void *this, const uint8_t *pal_img, int pal_stride,
packet->end_pts = endpts * 90000;
spudec_queue_packet(spu, packet);
}
+
+/**
+ * palette must contain at least 256 32-bit entries, otherwise crashes
+ * are possible
+ */
+void spudec_set_paletted(void *spu, const uint8_t *pal_img, int pal_stride,
+ const void *palette,
+ int x, int y, int w, int h,
+ double pts, double endpts)
+{
+ packet_t *packet = spudec_packet_create(x, y, w, h);
+ if (!packet)
+ return;
+ if (packet->data_len) // size 0 is a special "clear" packet
+ spudec_packet_fill(packet, pal_img, pal_stride, palette, 0, 0, w, h);
+ spudec_packet_send(spu, packet, pts, endpts);
+}
diff --git a/sub/spudec.h b/sub/spudec.h
index ad7ece4f7a..533ac511e8 100644
--- a/sub/spudec.h
+++ b/sub/spudec.h
@@ -39,5 +39,13 @@ void spudec_set_paletted(void *this, const uint8_t *pal_img, int stride,
const void *palette,
int x, int y, int w, int h,
double pts, double endpts);
+struct spu_packet_t *spudec_packet_create(int x, int y, int w, int h);
+void spudec_packet_fill(struct spu_packet_t *packet,
+ const uint8_t *pal_img, int pal_stride,
+ const void *palette,
+ int x, int y, int w, int h);
+void spudec_packet_send(void *spu, struct spu_packet_t *packet,
+ double pts, double endpts);
+void spudec_packet_clear(struct spu_packet_t *packet);
#endif /* MPLAYER_SPUDEC_H */