mirror of https://github.com/mpv-player/mpv
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
This commit is contained in:
parent
7e87c0e76a
commit
0dc290269d
52
sub/av_sub.c
52
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:
|
||||
|
|
94
sub/spudec.c
94
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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue