summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libvo/vo_bl.c106
1 files changed, 74 insertions, 32 deletions
diff --git a/libvo/vo_bl.c b/libvo/vo_bl.c
index 9452af8718..126ffccfba 100644
--- a/libvo/vo_bl.c
+++ b/libvo/vo_bl.c
@@ -11,6 +11,11 @@
* any later version")
*
* Other stuff: Copyright (C) Rik Snel 2002, License GNU GPL v2
+ *
+ * patch from Stefan Schuermans <1stein@schuermans.info>:
+ * - correction of "maxval" in Blinkenlights UDP protcol
+ * - new scheme for new HDL
+ * - new scheme for grayscale in arbitrary size
*/
#include <stdio.h>
@@ -189,21 +194,55 @@ static void udp_close(bl_host_t *h) {
closesocket(h->fd);
}
-#define NO_BLS 2
+#define NO_BLS 3
-/* currently only arcade is supported, hdl can be supported
- * in principle and future projects can be supported if their
- * parameters become known */
static bl_properties_t bls[NO_BLS] = {
- { "hdl", IMGFMT_BGR1, 1, 18, 8, 1,
- NULL, NULL, NULL, NULL, NULL, NULL },
+ { "hdl", IMGFMT_YV12, 1, 18, 8, 8,
+ &bml_init, &bml_write_frame, &bml_close,
+ &udp_init, &udp_send, &udp_close },
{ "arcade", IMGFMT_YV12, 1, 26, 20, 8,
&bml_init, &bml_write_frame, &bml_close,
+ &udp_init, &udp_send, &udp_close },
+ { "grayscale", IMGFMT_YV12, 1, -1, -1, 8, /* use width and height of movie */
+ &bml_init, &bml_write_frame, &bml_close,
&udp_init, &udp_send, &udp_close } };
static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width,
uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format)
{
+ void * ptr;
+
+ /* adapt size of Blinkenlights UDP stream to size of movie */
+ if (bl->width < 0 || bl->height < 0) {
+ if (bl->width < 0) /* use width of movie */
+ bl->width = width;
+ if (bl->height < 0) /* use height of movie */
+ bl->height = height;
+ /* check for maximum size of UDP packet */
+ if (12 + bl->width*bl->height*bl->channels > 65507) {
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: %dx%d-%d does not fit into an UDP packet\n",
+ bl->width, bl->height, bl->channels);
+ return 1;
+ }
+ /* resize frame and tmp buffers */
+ bl_size = 12 + bl->width*bl->height*bl->channels;
+ ptr = realloc(bl_packet, 12 + bl->width*bl->height*3); /* space for header and image data */
+ if (ptr)
+ bl_packet = (bl_packet_t*)ptr;
+ else {
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: out of memory error\n");
+ return 1;
+ }
+ image = ((unsigned char*)bl_packet + 12); /* pointer to image data */
+ ptr = realloc(tmp, bl->width*bl->height*3); /* space for image data only */
+ if (ptr)
+ tmp = (unsigned char*)ptr;
+ else {
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: out of memory error\n");
+ return 1;
+ }
+ }
+
framenum = 0;
if (format != IMGFMT_YV12) {
mp_msg(MSGT_VO, MSGL_ERR, "vo_bl called with wrong format");
@@ -245,20 +284,6 @@ static void flip_page (void) {
}
static uint32_t draw_frame(uint8_t * src[]) {
- int i, j;
- char *source, *dest;
- //printf("draw frame called\n");
-#if 0
- zr_info_t *zr = &zr_info[j];
- geo_t *g = &zr->g;
- source = src[0] + 2*g->yoff*zr->vdec*zr->stride + 2*g->xoff;
- dest = zr->image + 2*zr->off_y;
- for (i = 0; i < g->height/zr->vdec; i++) {
- memcpy(dest, source, zr->image_width*2);
- dest += 2*zr->image_width;
- source += zr->vdec*zr->stride;
- }
-#endif
return 0;
}
@@ -307,8 +332,9 @@ static uint32_t draw_slice(uint8_t *srcimg[], int stride[],
static uint32_t preinit(const char *arg) {
char *p, *q;
int end = 0, i;
+ char txt[256];
if (!arg || strlen(arg) == 0) {
- mp_msg(MSGT_VO, MSGL_ERR, "bl: subdevice must be given, example: -vo bl:arcade:host=localhost\n");
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: subdevice must be given, example: -vo bl:arcade:host=localhost:2323\n");
return 1;
}
@@ -320,12 +346,21 @@ static uint32_t preinit(const char *arg) {
p = bl_subdevice;
strcpy(p, arg);
mp_msg(MSGT_VO, MSGL_V, "bl: preinit called with %s\n", arg);
- if (strncmp(p, "arcade", 6)) {
- mp_msg(MSGT_VO, MSGL_ERR, "bl: subdevice must start with arcade, this is the only supported output format\nat the moment, i.e. -vo bl:arcade:host=localhost\n");
+ for (i = 0; i < NO_BLS; i++) {
+ if (!strncmp(p, bls[i].name, strlen(bls[i].name)))
+ break;
+ }
+ if (i >= NO_BLS) {
+ txt[0] = 0;
+ for (i = 0; i < NO_BLS; i++)
+ if (strlen( txt ) + 4 + strlen( bls[i].name ) + 1 < sizeof(txt))
+ sprintf( txt + strlen( txt ), "%s%s",
+ txt[0] == 0 ? "" : i == NO_BLS - 1 ? " or " : ", ", bls[i].name );
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: subdevice must start with %s\nbl: i.e. -vo bl:arcade:host=localhost:2323\n", txt);
return 1;
}
- bl = &bls[1];
- p += 6;
+ bl = &bls[i];
+ p += strlen(bls[i].name);
if (*p == '\0') {
no_bl_hosts = 1;
bl_hosts[0].name = "localhost";
@@ -342,7 +377,7 @@ static uint32_t preinit(const char *arg) {
q = p + 5;
if (!strncmp(p, "file=", 5)) {
if (no_bl_files == BL_MAX_FILES) {
- mp_msg(MSGT_VO, MSGL_ERR, "bl: maximum number of hosts reached (%d)\n", BL_MAX_FILES);
+ mp_msg(MSGT_VO, MSGL_ERR, "bl: maximum number of files reached (%d)\n", BL_MAX_FILES);
return 1;
}
p += 5;
@@ -385,11 +420,18 @@ static uint32_t preinit(const char *arg) {
p = ++q;
}
- bl_size = bl->width*bl->height*bl->channels + 12;
- /* enough space for RGB 24 bit + header */
- bl_packet = malloc(bl->width*bl->height*3+12);
- image = ((unsigned char*)bl_packet + 12);
- tmp = malloc(bl->width*bl->height*bl->channels);
+ if (bl->width >= 0 && bl->height >= 0) { /* size already known */
+ bl_size = 12 + bl->width*bl->height*bl->channels;
+ bl_packet = malloc(12 + bl->width*bl->height*3); /* space for header and image data */
+ image = ((unsigned char*)bl_packet + 12); /* pointer to image data */
+ tmp = malloc(bl->width*bl->height*3); /* space for image data only */
+ }
+ else { /* size unknown yet */
+ bl_size = 12;
+ bl_packet = malloc(12 + 3); /* space for header and a pixel */
+ image = ((unsigned char*)bl_packet + 12); /* pointer to image data */
+ tmp = malloc(3); /* space for a pixel only */
+ }
if (!bl_packet || !tmp) {
mp_msg(MSGT_VO, MSGL_ERR, "bl: out of memory error\n");
@@ -399,7 +441,7 @@ static uint32_t preinit(const char *arg) {
bl_packet->width = htons(bl->width);
bl_packet->height = htons(bl->height);
bl_packet->channels = htons(bl->channels);
- bl_packet->maxval = htons(2<<bl->bpc - 1);
+ bl_packet->maxval = htons((1 << bl->bpc) - 1);
/* open all files */
for (i = 0; i < no_bl_files; i++)