diff --git a/src/608_spupng.c b/src/608_spupng.c
index ba1677f6..9b7c802b 100644
--- a/src/608_spupng.c
+++ b/src/608_spupng.c
@@ -205,6 +205,7 @@ spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data,
int row;
int empty_buf = 1;
+ char str[256] = "";
for (row = 0; row < 15; row++)
{
if (data->row_used[row])
@@ -233,19 +234,7 @@ spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data,
sp->pngfile, strerror(errno));
}
fclose(sp->fppng);
-
- fprintf(sp->fpxml, "fpxml, " end=\"%.3f\"", ((double)ms_end) / 1000);
- dbg_print(CCX_DMT_608, " end=\"%.3f\"", ((double)ms_end) / 1000);
- fprintf(sp->fpxml, " image=\"%s\"", sp->pngfile);
- dbg_print(CCX_DMT_608, " image=\"%s\"", sp->pngfile);
- fprintf(sp->fpxml, " xoffset=\"%d\"", sp->xOffset);
- dbg_print(CCX_DMT_608, " xoffset=\"%d\"", sp->xOffset);
- fprintf(sp->fpxml, " yoffset=\"%d\"", sp->yOffset);
- dbg_print(CCX_DMT_608, " yoffset=\"%d\"", sp->yOffset);
- fprintf(sp->fpxml, ">\n\n");
- dbg_print(CCX_DMT_608, "-->\n");
-
- fflush(sp->fpxml);
-
+
+ write_spucomment(sp,str);
return 1;
}
int write_cc_buffer_as_spupng(struct eia608_screen *data,struct s_context_cc608 *context)
diff --git a/src/constants.h b/src/constants.h
index 39133b2d..0b7418ba 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -256,4 +256,7 @@ enum cxx_code_type
#define CCX_TXT_IN_USE 2 // Positive autodetected, or forced, etc
+#define CCX_OF_TYPE_TEXT 1
+#define CCX_OF_TYPE_IMAGE 2
+
#endif
diff --git a/src/dvb_subtitle_decoder.c b/src/dvb_subtitle_decoder.c
index 03de4e52..d3c8710b 100644
--- a/src/dvb_subtitle_decoder.c
+++ b/src/dvb_subtitle_decoder.c
@@ -32,8 +32,8 @@
#define snprintf(str,size,format,...) _snprintf(str,size-1,format,__VA_ARGS__)
#endif
-
#include "dvb_subtitle_decoder.h"
+#include "spupng_encoder.h"
#define DEBUG
#ifdef DEBUG
@@ -48,13 +48,11 @@
#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
#define DVBSUB_DISPLAY_SEGMENT 0x80
-
#define RL32(x) (*(unsigned int *)(x))
#define RB32(x) (ntohl(*(unsigned int *)(x)))
#define RL16(x) (*(unsigned short int*)(x))
#define RB16(x) (ntohs(*(unsigned short int*)(x)))
-
#define SCALEBITS 10
#define ONE_HALF (1 << (SCALEBITS - 1))
#define FIX(x) ((int) ((x) * (1<= INT_MAX - 7 || bit_size < 0 || !buffer) {
- buffer_size = bit_size = 0;
- buffer = NULL;
- ret = -1;
- errno = EINVAL;
- }
+ if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer)
+ {
+ buffer_size = bit_size = 0;
+ buffer = NULL;
+ ret = -1;
+ errno = EINVAL;
+ }
- buffer_size = (bit_size + 7) >> 3;
+ buffer_size = (bit_size + 7) >> 3;
- s->buffer = buffer;
- s->size_in_bits = bit_size;
- s->size_in_bits_plus8 = bit_size + 8;
- s->buffer_end = buffer + buffer_size;
- s->index = 0;
+ s->buffer = buffer;
+ s->size_in_bits = bit_size;
+ s->size_in_bits_plus8 = bit_size + 8;
+ s->buffer_end = buffer + buffer_size;
+ s->index = 0;
- return ret;
+ return ret;
}
static __inline int get_bits_count(const GetBitContext *s)
{
- return s->index;
+ return s->index;
}
static __inline unsigned int get_bits(GetBitContext *s, int n)
{
- register int tmp;
- unsigned int re_index = s->index;
- unsigned int re_cache = 0;
- unsigned int re_size_plus8 = s->size_in_bits_plus8;
+ register int tmp;
+ unsigned int re_index = s->index;
+ unsigned int re_cache = 0;
+ unsigned int re_size_plus8 = s->size_in_bits_plus8;
- if(n <=0 && n>25)
- return -1;
- re_cache = RB32( s->buffer + (re_index >> 3 )) << (re_index & 7);
+ if (n <= 0 && n > 25)
+ return -1;
+ re_cache = RB32( s->buffer + (re_index >> 3 )) << (re_index & 7);
- tmp = ((uint32_t) re_cache) >> (32 -n);
+ tmp = ((uint32_t) re_cache) >> (32 - n);
- re_index = ( (re_size_plus8 < re_index + (n) )? ( re_size_plus8 ) : ( re_index + (n)) );
+ re_index = (
+ (re_size_plus8 < re_index + (n)) ?
+ (re_size_plus8) : (re_index + (n)));
- s->index = re_index;
- return tmp;
+ s->index = re_index;
+ return tmp;
}
static __inline unsigned int get_bits1(GetBitContext *s)
{
- unsigned int index = s->index;
- uint8_t result = s->buffer[index >> 3];
+ unsigned int index = s->index;
+ uint8_t result = s->buffer[index >> 3];
- result <<= index & 7;
- result >>= 8 - 1;
+ result <<= index & 7;
+ result >>= 8 - 1;
- if (s->index < s->size_in_bits_plus8)
- index++;
- s->index = index;
+ if (s->index < s->size_in_bits_plus8)
+ index++;
+ s->index = index;
- return result;
+ return result;
}
static void freep(void *arg)
{
- void **ptr = (void **)arg;
- free(*ptr);
- *ptr = NULL;
+ void **ptr = (void **) arg;
+ if (*ptr)
+ free(*ptr);
+ *ptr = NULL;
}
#ifdef DEBUG
-static void png_save(const char *filename, uint32_t *bitmap, int w, int h)
+static int png_save1(const char *filename, uint8_t *bitmap, int w, int h,uint32_t *clut)
{
- FILE *f;
- char fname[40];
- png_structp png_ptr;
- png_infop info_ptr;
- png_bytep* row_pointer;
+ FILE *f = NULL;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_bytep* row_pointer = NULL;
+ int i, j, ret;
+ int k = 0;
static png_color palette[10] =
{
{ 0xff, 0xff, 0xff }, // COL_WHITE = 0,
@@ -229,291 +229,418 @@ static void png_save(const char *filename, uint32_t *bitmap, int w, int h)
{ 0x00, 0x00, 0x00 }, // COL_BLACK = 8
{ 0x00, 0x00, 0x00 } // COL_TRANSPARENT = 9
};
+
static png_byte alpha[10] =
- {255,255,255,255,255,255,255,255,255,0};
- int i =0;
- int j =0;
- int k =0;
- unsigned char array[1024] = "";
+ {
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 255,
+ 0
+ };
+ f = fopen(filename, "wb");
+ if (!f)
+ {
+ mprint("DVB:unable to open %s in write mode \n", filename);
+ ret = -1;
+ goto end;
+ }
- snprintf(fname, sizeof(fname), "%s.png", filename);
- f = fopen(fname, "wb");
+ if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
+ NULL )))
+ {
+ mprint("DVB:unable to create png write struct\n");
+ goto end;
+ }
+ if (!(info_ptr = png_create_info_struct(png_ptr)))
+ {
+ mprint("DVB:unable to create png info struct\n");
+ ret = -1;
+ goto end;
+ }
+
+ row_pointer = (png_bytep*) malloc(sizeof(png_bytep) * h);
+ if (!row_pointer)
+ {
+ mprint("DVB: unable to allocate row_pointer\n");
+ ret = -1;
+ goto end;
+ }
+ memset(row_pointer, 0, sizeof(png_bytep) * h);
+ png_init_io(png_ptr, f);
+
+ png_set_IHDR (png_ptr,
+ info_ptr,
+ w,
+ h,
+ /* bit_depth */ 8,
+ PNG_COLOR_TYPE_PALETTE,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ png_set_PLTE (png_ptr, info_ptr, palette, sizeof(palette) / sizeof(palette[0]));
+ png_set_tRNS (png_ptr, info_ptr, alpha, sizeof(alpha) / sizeof(alpha[0]), NULL);
+
+ for (i = 0; i < h; i++)
+ {
+ row_pointer[i] = (png_byte*) malloc(
+ png_get_rowbytes(png_ptr, info_ptr));
+ if (row_pointer[i] == NULL )
+ break;
+ }
+ if (i != h)
+ {
+ mprint("DVB: unable to allocate row_pointer internals\n");
+ ret = -1;
+ goto end;
+ }
+
+ png_write_info(png_ptr, info_ptr);
+
+ for (i = 0; i < h; i++)
+ {
+ for (j = 0; j < png_get_rowbytes(png_ptr, info_ptr); j ++)
+ {
+ k = bitmap[i * w + (j)];
+ row_pointer[i][j] = k;//((k >> 16) & 0xff);
+ }
+ }
+
+ png_write_image(png_ptr, row_pointer);
+
+ png_write_end(png_ptr, info_ptr);
+ end:if (row_pointer)
+ {
+ for (i = 0; i < h; i++)
+ freep(&row_pointer[i]);
+ freep(&row_pointer);
+ }
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (f)
+ fclose(f);
+ return ret;
+
+}
+static int png_save(const char *filename, uint32_t *bitmap, int w, int h)
+{
+ FILE *f = NULL;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_bytep* row_pointer = NULL;
+ int i, j, ret;
+ int k = 0;
+ f = fopen(filename, "wb");
if (!f)
{
- perror(fname);
- return;
+ mprint("DVB:unable to open %s in write mode \n", filename);
+ ret = -1;
+ goto end;
}
- if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL)))
+ if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
+ NULL )))
{
- printf("unable to create png write struct\n");
+ mprint("DVB:unable to create png write struct\n");
+ goto end;
}
-
if (!(info_ptr = png_create_info_struct(png_ptr)))
{
- printf("unable to create png info struct\n");
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+ mprint("DVB:unable to create png info struct\n");
+ ret = -1;
+ goto end;
}
- row_pointer = (png_bytep*)malloc(sizeof(png_bytep) * h);
- if(!row_pointer)
+ row_pointer = (png_bytep*) malloc(sizeof(png_bytep) * h);
+ if (!row_pointer)
{
- printf("unable to allocate row_pointer\n");
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
+ mprint("DVB: unable to allocate row_pointer\n");
+ ret = -1;
+ goto end;
}
+ memset(row_pointer, 0, sizeof(png_bytep) * h);
+ png_init_io(png_ptr, f);
- png_init_io(png_ptr,f);
-
- png_set_IHDR (png_ptr,info_ptr,w,h,
- /* bit_depth */ 8,PNG_COLOR_TYPE_RGB_ALPHA,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
-
- for (i = 0; i < h; i++)
- row_pointer[i] = (png_byte*)malloc(png_get_rowbytes(png_ptr,info_ptr));
-
- png_set_tRNS (png_ptr, info_ptr, alpha, sizeof(alpha) / sizeof(alpha[0]), NULL);
- png_write_info (png_ptr, info_ptr);
+ png_set_IHDR(png_ptr, info_ptr, w, h,
+ /* bit_depth */8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
for (i = 0; i < h; i++)
{
- for(j = 0 ; j < png_get_rowbytes(png_ptr,info_ptr) ; j+=4)
+ row_pointer[i] = (png_byte*) malloc(
+ png_get_rowbytes(png_ptr, info_ptr));
+ if (row_pointer[i] == NULL )
+ break;
+ }
+ if (i != h)
+ {
+ mprint("DVB: unable to allocate row_pointer internals\n");
+ ret = -1;
+ goto end;
+ }
+
+ png_write_info(png_ptr, info_ptr);
+
+ for (i = 0; i < h; i++)
+ {
+ for (j = 0; j < png_get_rowbytes(png_ptr, info_ptr); j += 4)
{
- k = bitmap[i * w + (j/4)];
+ k = bitmap[i * w + (j / 4)];
row_pointer[i][j] = ((k >> 16) & 0xff);
- row_pointer[i][j+1] = ((k >> 8) & 0xff);
- row_pointer[i][j+2] = ((k) & 0xff);
- row_pointer[i][j+3] = (k >> 24) & 0xff;
+ row_pointer[i][j + 1] = ((k >> 8) & 0xff);
+ row_pointer[i][j + 2] = ((k) & 0xff);
+ row_pointer[i][j + 3] = (k >> 24) & 0xff;
}
}
- png_write_image (png_ptr, row_pointer);
+ png_write_image(png_ptr, row_pointer);
- png_write_end (png_ptr, info_ptr);
-
- for (i = 0; i < h; i++)
- free(row_pointer[i]);
- free(row_pointer);
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
- fclose(f);
+ png_write_end(png_ptr, info_ptr);
+ end: if (row_pointer)
+ {
+ for (i = 0; i < h; i++)
+ freep(&row_pointer[i]);
+ freep(&row_pointer);
+ }
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (f)
+ fclose(f);
+ return ret;
}
#endif
#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-typedef struct DVBSubCLUT {
- int id;
- int version;
+typedef struct DVBSubCLUT
+{
+ int id;
+ int version;
- uint32_t clut4[4];
- uint32_t clut16[16];
- uint32_t clut256[256];
+ uint32_t clut4[4];
+ uint32_t clut16[16];
+ uint32_t clut256[256];
- struct DVBSubCLUT *next;
+ struct DVBSubCLUT *next;
} DVBSubCLUT;
static DVBSubCLUT default_clut;
-typedef struct DVBSubObjectDisplay {
- int object_id;
- int region_id;
+typedef struct DVBSubObjectDisplay
+{
+ int object_id;
+ int region_id;
- int x_pos;
- int y_pos;
+ int x_pos;
+ int y_pos;
- int fgcolor;
- int bgcolor;
+ int fgcolor;
+ int bgcolor;
- struct DVBSubObjectDisplay *region_list_next;
- struct DVBSubObjectDisplay *object_list_next;
+ struct DVBSubObjectDisplay *region_list_next;
+ struct DVBSubObjectDisplay *object_list_next;
} DVBSubObjectDisplay;
-typedef struct DVBSubObject {
- int id;
- int version;
+typedef struct DVBSubObject
+{
+ int id;
+ int version;
- int type;
+ int type;
- DVBSubObjectDisplay *display_list;
+ DVBSubObjectDisplay *display_list;
- struct DVBSubObject *next;
+ struct DVBSubObject *next;
} DVBSubObject;
-typedef struct DVBSubRegionDisplay {
- int region_id;
+typedef struct DVBSubRegionDisplay
+{
+ int region_id;
- int x_pos;
- int y_pos;
+ int x_pos;
+ int y_pos;
- struct DVBSubRegionDisplay *next;
+ struct DVBSubRegionDisplay *next;
} DVBSubRegionDisplay;
-typedef struct DVBSubRegion {
- int id;
- int version;
+typedef struct DVBSubRegion
+{
+ int id;
+ int version;
- int width;
- int height;
- int depth;
+ int width;
+ int height;
+ int depth;
- int clut;
- int bgcolor;
+ int clut;
+ int bgcolor;
- uint8_t *pbuf;
- int buf_size;
- int dirty;
+ uint8_t *pbuf;
+ int buf_size;
+ int dirty;
- DVBSubObjectDisplay *display_list;
+ DVBSubObjectDisplay *display_list;
- struct DVBSubRegion *next;
+ struct DVBSubRegion *next;
} DVBSubRegion;
-typedef struct DVBSubDisplayDefinition {
- int version;
+typedef struct DVBSubDisplayDefinition
+{
+ int version;
- int x;
- int y;
- int width;
- int height;
+ int x;
+ int y;
+ int width;
+ int height;
} DVBSubDisplayDefinition;
-typedef struct DVBSubContext {
- int composition_id;
- int ancillary_id;
+typedef struct DVBSubContext
+{
+ int composition_id;
+ int ancillary_id;
- int version;
- int time_out;
- DVBSubRegion *region_list;
- DVBSubCLUT *clut_list;
- DVBSubObject *object_list;
+ int version;
+ int time_out;
+ DVBSubRegion *region_list;
+ DVBSubCLUT *clut_list;
+ DVBSubObject *object_list;
- DVBSubRegionDisplay *display_list;
- DVBSubDisplayDefinition *display_definition;
+ DVBSubRegionDisplay *display_list;
+ DVBSubDisplayDefinition *display_definition;
+ struct ccx_s_write *out;
} DVBSubContext;
-
static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
{
- DVBSubObject *ptr = ctx->object_list;
+ DVBSubObject *ptr = ctx->object_list;
- while (ptr && ptr->id != object_id) {
- ptr = ptr->next;
- }
+ while (ptr && ptr->id != object_id)
+ ptr = ptr->next;
- return ptr;
+ return ptr;
}
static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
{
- DVBSubCLUT *ptr = ctx->clut_list;
+ DVBSubCLUT *ptr = ctx->clut_list;
- while (ptr && ptr->id != clut_id) {
- ptr = ptr->next;
- }
+ while (ptr && ptr->id != clut_id)
+ ptr = ptr->next;
- return ptr;
+ return ptr;
}
static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
{
- DVBSubRegion *ptr = ctx->region_list;
+ DVBSubRegion *ptr = ctx->region_list;
- while (ptr && ptr->id != region_id) {
- ptr = ptr->next;
- }
+ while (ptr && ptr->id != region_id)
+ ptr = ptr->next;
- return ptr;
+ return ptr;
}
static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
{
- DVBSubObject *object, *obj2, **obj2_ptr;
- DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
+ DVBSubObject *object, *obj2, **obj2_ptr;
+ DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
- while (region->display_list) {
- display = region->display_list;
+ while (region->display_list)
+ {
+ display = region->display_list;
- object = get_object(ctx, display->object_id);
+ object = get_object(ctx, display->object_id);
- if (object) {
- obj_disp_ptr = &object->display_list;
- obj_disp = *obj_disp_ptr;
+ if (object)
+ {
+ obj_disp_ptr = &object->display_list;
+ obj_disp = *obj_disp_ptr;
- while (obj_disp && obj_disp != display) {
- obj_disp_ptr = &obj_disp->object_list_next;
- obj_disp = *obj_disp_ptr;
- }
+ while (obj_disp && obj_disp != display)
+ {
+ obj_disp_ptr = &obj_disp->object_list_next;
+ obj_disp = *obj_disp_ptr;
+ }
- if (obj_disp) {
- *obj_disp_ptr = obj_disp->object_list_next;
+ if (obj_disp)
+ {
+ *obj_disp_ptr = obj_disp->object_list_next;
- if (!object->display_list) {
- obj2_ptr = &ctx->object_list;
- obj2 = *obj2_ptr;
+ if (!object->display_list)
+ {
+ obj2_ptr = &ctx->object_list;
+ obj2 = *obj2_ptr;
- while (obj2 != object) {
- assert(obj2);
- obj2_ptr = &obj2->next;
- obj2 = *obj2_ptr;
- }
+ while (obj2 != object)
+ {
+ assert(obj2);
+ obj2_ptr = &obj2->next;
+ obj2 = *obj2_ptr;
+ }
- *obj2_ptr = obj2->next;
+ *obj2_ptr = obj2->next;
- free(obj2);
- }
- }
- }
+ free(obj2);
+ }
+ }
+ }
- region->display_list = display->region_list_next;
+ region->display_list = display->region_list_next;
- free(display);
- }
+ free(display);
+ }
}
static void delete_cluts(DVBSubContext *ctx)
{
- DVBSubCLUT *clut;
+ DVBSubCLUT *clut;
- while (ctx->clut_list) {
- clut = ctx->clut_list;
+ while (ctx->clut_list)
+ {
+ clut = ctx->clut_list;
- ctx->clut_list = clut->next;
+ ctx->clut_list = clut->next;
- free(clut);
- }
+ free(clut);
+ }
}
static void delete_objects(DVBSubContext *ctx)
{
- DVBSubObject *object;
+ DVBSubObject *object;
- while (ctx->object_list) {
- object = ctx->object_list;
+ while (ctx->object_list)
+ {
+ object = ctx->object_list;
- ctx->object_list = object->next;
+ ctx->object_list = object->next;
- free(object);
- }
+ free(object);
+ }
}
static void delete_regions(DVBSubContext *ctx)
{
- DVBSubRegion *region;
+ DVBSubRegion *region;
- while (ctx->region_list) {
- region = ctx->region_list;
+ while (ctx->region_list)
+ {
+ region = ctx->region_list;
- ctx->region_list = region->next;
+ ctx->region_list = region->next;
- delete_region_display_list(ctx, region);
+ delete_region_display_list(ctx, region);
- free(region->pbuf);
- free(region);
- }
+ free(region->pbuf);
+ free(region);
+ }
}
/**
* @param composition_id composition-page_id found in Subtitle descriptors
@@ -526,1114 +653,1230 @@ static void delete_regions(DVBSubContext *ctx)
* @return DVB context kept as void* for abstraction
*
*/
-void* dvbsub_init_decoder(int composition_id,int ancillary_id)
+void* dvbsub_init_decoder(int composition_id, int ancillary_id)
{
- int i, r, g, b, a = 0;
- DVBSubContext *ctx = (DVBSubContext*)malloc(sizeof(DVBSubContext));
- memset(ctx,0,sizeof(DVBSubContext));
+ int i, r, g, b, a = 0;
+ DVBSubContext *ctx = (DVBSubContext*) malloc(sizeof(DVBSubContext));
+ memset(ctx, 0, sizeof(DVBSubContext));
- ctx->composition_id = composition_id;
- ctx->ancillary_id = ancillary_id;
+ ctx->composition_id = composition_id;
+ ctx->ancillary_id = ancillary_id;
- ctx->version = -1;
+ ctx->version = -1;
- default_clut.id = -1;
- default_clut.next = NULL;
+ default_clut.id = -1;
+ default_clut.next = NULL;
- default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
- default_clut.clut4[1] = RGBA(255, 255, 255, 255);
- default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
- default_clut.clut4[3] = RGBA(127, 127, 127, 255);
+ default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
+ default_clut.clut4[1] = RGBA(255, 255, 255, 255);
+ default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
+ default_clut.clut4[3] = RGBA(127, 127, 127, 255);
- default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
- for (i = 1; i < 16; i++) {
- if (i < 8) {
- r = (i & 1) ? 255 : 0;
- g = (i & 2) ? 255 : 0;
- b = (i & 4) ? 255 : 0;
- } else {
- r = (i & 1) ? 127 : 0;
- g = (i & 2) ? 127 : 0;
- b = (i & 4) ? 127 : 0;
- }
- default_clut.clut16[i] = RGBA(r, g, b, 255);
- }
+ default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
+ for (i = 1; i < 16; i++)
+ {
+ if (i < 8)
+ {
+ r = (i & 1) ? 255 : 0;
+ g = (i & 2) ? 255 : 0;
+ b = (i & 4) ? 255 : 0;
+ }
+ else
+ {
+ r = (i & 1) ? 127 : 0;
+ g = (i & 2) ? 127 : 0;
+ b = (i & 4) ? 127 : 0;
+ }
+ default_clut.clut16[i] = RGBA(r, g, b, 255);
+ }
- default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
- for (i = 1; i < 256; i++) {
- if (i < 8) {
- r = (i & 1) ? 255 : 0;
- g = (i & 2) ? 255 : 0;
- b = (i & 4) ? 255 : 0;
- a = 63;
- } else {
- switch (i & 0x88) {
- case 0x00:
- r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
- g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
- b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
- a = 255;
- break;
- case 0x08:
- r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
- g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
- b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
- a = 127;
- break;
- case 0x80:
- r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
- g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
- b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
- a = 255;
- break;
- case 0x88:
- r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
- g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
- b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
- a = 255;
- break;
- }
- }
- default_clut.clut256[i] = RGBA(r, g, b, a);
- }
+ default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
+ for (i = 1; i < 256; i++)
+ {
+ if (i < 8)
+ {
+ r = (i & 1) ? 255 : 0;
+ g = (i & 2) ? 255 : 0;
+ b = (i & 4) ? 255 : 0;
+ a = 63;
+ }
+ else
+ {
+ switch (i & 0x88)
+ {
+ case 0x00:
+ r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
+ g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
+ b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
+ a = 255;
+ break;
+ case 0x08:
+ r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
+ g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
+ b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
+ a = 127;
+ break;
+ case 0x80:
+ r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
+ g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
+ b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
+ a = 255;
+ break;
+ case 0x88:
+ r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
+ g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
+ b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
+ a = 255;
+ break;
+ }
+ }
+ default_clut.clut256[i] = RGBA(r, g, b, a);
+ }
- return (void*)ctx;
+ return (void*) ctx;
}
int dvbsub_close_decoder(void *dvb_ctx)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
- DVBSubRegionDisplay *display;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
+ DVBSubRegionDisplay *display;
- delete_regions(ctx);
+ delete_regions(ctx);
- delete_objects(ctx);
+ delete_objects(ctx);
- delete_cluts(ctx);
+ delete_cluts(ctx);
- freep(&ctx->display_definition);
+ freep(&ctx->display_definition);
- while (ctx->display_list) {
- display = ctx->display_list;
- ctx->display_list = display->next;
- free(display);
- }
+ while (ctx->display_list)
+ {
+ display = ctx->display_list;
+ ctx->display_list = display->next;
+ free(display);
+ }
- return 0;
+ return 0;
}
static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
+ const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table,
+ int x_pos)
{
- GetBitContext gb;
+ GetBitContext gb;
- int bits;
- int run_length;
- int pixels_read = x_pos;
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
- init_get_bits(&gb, *srcbuf, buf_size << 3);
+ init_get_bits(&gb, *srcbuf, buf_size << 3);
- destbuf += x_pos;
+ destbuf += x_pos;
- while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
- bits = get_bits(&gb, 2);
+ while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len)
+ {
+ bits = get_bits(&gb, 2);
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = get_bits1(&gb);
- if (bits == 1) {
- run_length = get_bits(&gb, 3) + 3;
- bits = get_bits(&gb, 2);
+ if (bits)
+ {
+ if (non_mod != 1 || bits != 1)
+ {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ }
+ else
+ {
+ bits = get_bits1(&gb);
+ if (bits == 1)
+ {
+ run_length = get_bits(&gb, 3) + 3;
+ bits = get_bits(&gb, 2);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- bits = get_bits(&gb, 2);
- if (bits == 2) {
- run_length = get_bits(&gb, 4) + 12;
- bits = get_bits(&gb, 2);
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else
+ {
+ bits = get_bits1(&gb);
+ if (bits == 0)
+ {
+ bits = get_bits(&gb, 2);
+ if (bits == 2)
+ {
+ run_length = get_bits(&gb, 4) + 12;
+ bits = get_bits(&gb, 2);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 3) {
- run_length = get_bits(&gb, 8) + 29;
- bits = get_bits(&gb, 2);
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else if (bits == 3)
+ {
+ run_length = get_bits(&gb, 8) + 29;
+ bits = get_bits(&gb, 2);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 1) {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- run_length = 2;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
- }
- } else {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- }
- }
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else if (bits == 1)
+ {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ run_length = 2;
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ else
+ {
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ return pixels_read;
+ }
+ }
+ else
+ {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ }
- if (get_bits(&gb, 6))
- printf("DVBSub error: line overflow\n");
+ if (get_bits(&gb, 6))
+ mprint("DVBSub error: line overflow\n");
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
+ return pixels_read;
}
static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
+ const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table,
+ int x_pos)
{
- GetBitContext gb;
+ GetBitContext gb;
- int bits;
- int run_length;
- int pixels_read = x_pos;
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
- init_get_bits(&gb, *srcbuf, buf_size << 3);
+ init_get_bits(&gb, *srcbuf, buf_size << 3);
- destbuf += x_pos;
+ destbuf += x_pos;
- while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
- bits = get_bits(&gb, 4);
+ while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len)
+ {
+ bits = get_bits(&gb, 4);
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- run_length = get_bits(&gb, 3);
+ if (bits)
+ {
+ if (non_mod != 1 || bits != 1)
+ {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ }
+ else
+ {
+ bits = get_bits1(&gb);
+ if (bits == 0)
+ {
+ run_length = get_bits(&gb, 3);
- if (run_length == 0) {
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
- }
+ if (run_length == 0)
+ {
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ return pixels_read;
+ }
- run_length += 2;
+ run_length += 2;
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- run_length = get_bits(&gb, 2) + 4;
- bits = get_bits(&gb, 4);
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ else
+ {
+ bits = get_bits1(&gb);
+ if (bits == 0)
+ {
+ run_length = get_bits(&gb, 2) + 4;
+ bits = get_bits(&gb, 4);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else {
- bits = get_bits(&gb, 2);
- if (bits == 2) {
- run_length = get_bits(&gb, 4) + 9;
- bits = get_bits(&gb, 4);
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else
+ {
+ bits = get_bits(&gb, 2);
+ if (bits == 2)
+ {
+ run_length = get_bits(&gb, 4) + 9;
+ bits = get_bits(&gb, 4);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 3) {
- run_length = get_bits(&gb, 8) + 25;
- bits = get_bits(&gb, 4);
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else if (bits == 3)
+ {
+ run_length = get_bits(&gb, 8) + 25;
+ bits = get_bits(&gb, 4);
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 1) {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- run_length = 2;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- *destbuf++ = bits;
- pixels_read ++;
- }
- }
- }
- }
- }
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else
+ {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ else if (bits == 1)
+ {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ run_length = 2;
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ else
+ {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ }
+ }
- if (get_bits(&gb, 8))
- printf("DVBSub error: line overflow\n");
+ if (get_bits(&gb, 8))
+ mprint("DVBSub error: line overflow\n");
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
+ return pixels_read;
}
static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
+ const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table,
+ int x_pos)
{
- const uint8_t *sbuf_end = (*srcbuf) + buf_size;
- int bits;
- int run_length;
- int pixels_read = x_pos;
+ const uint8_t *sbuf_end = (*srcbuf) + buf_size;
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
- destbuf += x_pos;
+ destbuf += x_pos;
- while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
- bits = *(*srcbuf)++;
+ while (*srcbuf < sbuf_end && pixels_read < dbuf_len)
+ {
+ bits = *(*srcbuf)++;
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = *(*srcbuf)++;
- run_length = bits & 0x7f;
- if ((bits & 0x80) == 0) {
- if (run_length == 0) {
- return pixels_read;
- }
+ if (bits)
+ {
+ if (non_mod != 1 || bits != 1)
+ {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ }
+ else
+ {
+ bits = *(*srcbuf)++;
+ run_length = bits & 0x7f;
+ if ((bits & 0x80) == 0)
+ {
+ if (run_length == 0)
+ {
+ return pixels_read;
+ }
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- bits = *(*srcbuf)++;
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ else
+ {
+ bits = *(*srcbuf)++;
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- if (map_table)
- bits = map_table[bits];
- else while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- }
- }
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ if (map_table)
+ bits = map_table[bits];
+ else
+ while (run_length-- > 0 && pixels_read < dbuf_len)
+ {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ }
- if (*(*srcbuf)++)
- printf("DVBSub error: line overflow\n");
+ if (*(*srcbuf)++)
+ mprint("DVBSub error: line overflow\n");
- return pixels_read;
+ return pixels_read;
}
-
-
-static void dvbsub_parse_pixel_data_block(void *dvb_ctx, DVBSubObjectDisplay *display,
- const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
+static void dvbsub_parse_pixel_data_block(void *dvb_ctx,
+ DVBSubObjectDisplay *display, const uint8_t *buf, int buf_size,
+ int top_bottom, int non_mod)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
- DVBSubRegion *region = get_region(ctx, display->region_id);
- const uint8_t *buf_end = buf + buf_size;
- uint8_t *pbuf;
- int x_pos, y_pos;
- int i;
+ DVBSubRegion *region = get_region(ctx, display->region_id);
+ const uint8_t *buf_end = buf + buf_size;
+ uint8_t *pbuf;
+ int x_pos, y_pos;
+ int i;
- uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
- uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
- uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
- uint8_t *map_table;
+ uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf };
+ uint8_t map2to8[] = { 0x00, 0x77, 0x88, 0xff };
+ uint8_t map4to8[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
+ uint8_t *map_table;
- if (region == 0)
- return;
+ if (region == 0)
+ return;
- pbuf = region->pbuf;
- region->dirty = 1;
+ pbuf = region->pbuf;
+ region->dirty = 1;
- x_pos = display->x_pos;
- y_pos = display->y_pos;
+ x_pos = display->x_pos;
+ y_pos = display->y_pos;
- y_pos += top_bottom;
+ y_pos += top_bottom;
- while (buf < buf_end) {
- if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
- printf("Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
- return;
- }
+ while (buf < buf_end)
+ {
+ if ((*buf != 0xf0 && x_pos >= region->width) || y_pos >= region->height)
+ {
+ mprint("Invalid object location! %d-%d %d-%d %02x\n", x_pos,
+ region->width, y_pos, region->height, *buf);
+ return;
+ }
- switch (*buf++) {
- case 0x10:
- if (region->depth == 8)
- map_table = map2to8;
- else if (region->depth == 4)
- map_table = map2to4;
- else
- map_table = NULL;
+ switch (*buf++)
+ {
+ case 0x10:
+ if (region->depth == 8)
+ map_table = map2to8;
+ else if (region->depth == 4)
+ map_table = map2to4;
+ else
+ map_table = NULL;
- x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, map_table, x_pos);
- break;
- case 0x11:
- if (region->depth < 4) {
- printf("4-bit pixel string in %d-bit region!\n", region->depth);
- return;
- }
+ x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf, non_mod, map_table,
+ x_pos);
+ break;
+ case 0x11:
+ if (region->depth < 4)
+ {
+ mprint("4-bit pixel string in %d-bit region!\n",
+ region->depth);
+ return;
+ }
- if (region->depth == 8)
- map_table = map4to8;
- else
- map_table = NULL;
+ if (region->depth == 8)
+ map_table = map4to8;
+ else
+ map_table = NULL;
- x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, map_table, x_pos);
- break;
- case 0x12:
- if (region->depth < 8) {
- printf("8-bit pixel string in %d-bit region!\n", region->depth);
- return;
- }
+ x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf, non_mod, map_table,
+ x_pos);
+ break;
+ case 0x12:
+ if (region->depth < 8)
+ {
+ mprint("8-bit pixel string in %d-bit region!\n",
+ region->depth);
+ return;
+ }
- x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, NULL, x_pos);
- break;
+ x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf, non_mod, NULL,
+ x_pos);
+ break;
- case 0x20:
- map2to4[0] = (*buf) >> 4;
- map2to4[1] = (*buf++) & 0xf;
- map2to4[2] = (*buf) >> 4;
- map2to4[3] = (*buf++) & 0xf;
- break;
- case 0x21:
- for (i = 0; i < 4; i++)
- map2to8[i] = *buf++;
- break;
- case 0x22:
- for (i = 0; i < 16; i++)
- map4to8[i] = *buf++;
- break;
+ case 0x20:
+ map2to4[0] = (*buf) >> 4;
+ map2to4[1] = (*buf++) & 0xf;
+ map2to4[2] = (*buf) >> 4;
+ map2to4[3] = (*buf++) & 0xf;
+ break;
+ case 0x21:
+ for (i = 0; i < 4; i++)
+ map2to8[i] = *buf++;
+ break;
+ case 0x22:
+ for (i = 0; i < 16; i++)
+ map4to8[i] = *buf++;
+ break;
- case 0xf0:
- x_pos = display->x_pos;
- y_pos += 2;
- break;
- default:
- printf("Unknown/unsupported pixel block 0x%x\n", *(buf-1));
- }
- }
+ case 0xf0:
+ x_pos = display->x_pos;
+ y_pos += 2;
+ break;
+ default:
+ mprint("Unknown/unsupported pixel block 0x%x\n", *(buf - 1));
+ /* no break */
+ }
+ }
}
-static void dvbsub_parse_object_segment(void *dvb_ctx,
- const uint8_t *buf, int buf_size)
+static void dvbsub_parse_object_segment(void *dvb_ctx, const uint8_t *buf,
+ int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext*)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext*) dvb_ctx;
- const uint8_t *buf_end = buf + buf_size;
- int object_id;
- DVBSubObject *object;
- DVBSubObjectDisplay *display;
- int top_field_len, bottom_field_len;
+ const uint8_t *buf_end = buf + buf_size;
+ int object_id;
+ DVBSubObject *object;
+ DVBSubObjectDisplay *display;
+ int top_field_len, bottom_field_len;
- int coding_method, non_modifying_color;
+ int coding_method, non_modifying_color;
- object_id = RB16(buf);
- buf += 2;
+ object_id = RB16(buf);
+ buf += 2;
- object = get_object(ctx, object_id);
+ object = get_object(ctx, object_id);
- if (!object)
- return;
+ if (!object)
+ return;
- coding_method = ((*buf) >> 2) & 3;
- non_modifying_color = ((*buf++) >> 1) & 1;
+ coding_method = ((*buf) >> 2) & 3;
+ non_modifying_color = ((*buf++) >> 1) & 1;
- if (coding_method == 0) {
- top_field_len = RB16(buf);
- buf += 2;
- bottom_field_len = RB16(buf);
- buf += 2;
+ if (coding_method == 0)
+ {
+ top_field_len = RB16(buf);
+ buf += 2;
+ bottom_field_len = RB16(buf);
+ buf += 2;
- if (buf + top_field_len + bottom_field_len > buf_end) {
- printf( "Field data size too large\n");
- return;
- }
+ if (buf + top_field_len + bottom_field_len > buf_end)
+ {
+ mprint("Field data size too large\n");
+ return;
+ }
- for (display = object->display_list; display; display = display->object_list_next) {
- const uint8_t *block = buf;
- int bfl = bottom_field_len;
+ for (display = object->display_list; display;
+ display = display->object_list_next)
+ {
+ const uint8_t *block = buf;
+ int bfl = bottom_field_len;
- dvbsub_parse_pixel_data_block(dvb_ctx, display, block, top_field_len, 0,
- non_modifying_color);
+ dvbsub_parse_pixel_data_block(dvb_ctx, display, block,
+ top_field_len, 0, non_modifying_color);
- if (bottom_field_len > 0)
- block = buf + top_field_len;
- else
- bfl = top_field_len;
+ if (bottom_field_len > 0)
+ block = buf + top_field_len;
+ else
+ bfl = top_field_len;
- dvbsub_parse_pixel_data_block(dvb_ctx, display, block, bfl, 1,
- non_modifying_color);
- }
+ dvbsub_parse_pixel_data_block(dvb_ctx, display, block, bfl, 1,
+ non_modifying_color);
+ }
- } else if (coding_method == 1) {
- printf( "FIXME support for sring coding standard\n");
- } else {
- printf( "Unknown object coding %d\n", coding_method);
- }
+ }
+ else if (coding_method == 1)
+ {
+ mprint("FIXME support for sring coding standard\n");
+ }
+ else
+ {
+ mprint("Unknown object coding %d\n", coding_method);
+ }
}
-static int dvbsub_parse_clut_segment(void *dvb_ctx,
- const uint8_t *buf, int buf_size)
+static int dvbsub_parse_clut_segment(void *dvb_ctx, const uint8_t *buf,
+ int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext*)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext*) dvb_ctx;
- const uint8_t *buf_end = buf + buf_size;
- int i, clut_id;
- int version;
- DVBSubCLUT *clut;
- int entry_id, depth , full_range;
- int y, cr, cb, alpha;
- int r, g, b, r_add, g_add, b_add;
+ const uint8_t *buf_end = buf + buf_size;
+ int clut_id;
+ int version;
+ DVBSubCLUT *clut;
+ int entry_id, depth, full_range;
+ int y, cr, cb, alpha;
+ int r, g, b, r_add, g_add, b_add;
- printf("DVB clut packet:\n");
+ clut_id = *buf++;
+ version = ((*buf) >> 4) & 15;
+ buf += 1;
- for (i=0; i < buf_size; i++) {
- printf("%02x ", buf[i]);
- if (i % 16 == 15)
- printf("\n");
- }
+ clut = get_clut(ctx, clut_id);
- if (i % 16)
- printf("\n");
+ if (!clut)
+ {
+ clut = (DVBSubCLUT*) malloc(sizeof(DVBSubCLUT));
- clut_id = *buf++;
- version = ((*buf)>>4)&15;
- buf += 1;
+ memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
- clut = get_clut(ctx, clut_id);
+ clut->id = clut_id;
+ clut->version = -1;
- if (!clut) {
- clut = (DVBSubCLUT*)malloc(sizeof(DVBSubCLUT));
+ clut->next = ctx->clut_list;
+ ctx->clut_list = clut;
+ }
- memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
+ if (clut->version != version)
+ {
- clut->id = clut_id;
- clut->version = -1;
+ clut->version = version;
- clut->next = ctx->clut_list;
- ctx->clut_list = clut;
- }
+ while (buf + 4 < buf_end)
+ {
+ entry_id = *buf++;
- if (clut->version != version) {
+ depth = (*buf) & 0xe0;
- clut->version = version;
+ if (depth == 0)
+ {
+ mprint("Invalid clut depth 0x%x!\n", *buf);
+ return 0;
+ }
- while (buf + 4 < buf_end) {
- entry_id = *buf++;
+ full_range = (*buf++) & 1;
- depth = (*buf) & 0xe0;
+ if (full_range)
+ {
+ y = *buf++;
+ cr = *buf++;
+ cb = *buf++;
+ alpha = *buf++;
+ }
+ else
+ {
+ y = buf[0] & 0xfc;
+ cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
+ cb = (buf[1] << 2) & 0xf0;
+ alpha = (buf[1] << 6) & 0xc0;
- if (depth == 0) {
- printf( "Invalid clut depth 0x%x!\n", *buf);
- return 0;
- }
+ buf += 2;
+ }
- full_range = (*buf++) & 1;
+ if (y == 0)
+ alpha = 0xff;
- if (full_range) {
- y = *buf++;
- cr = *buf++;
- cb = *buf++;
- alpha = *buf++;
- } else {
- y = buf[0] & 0xfc;
- cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
- cb = (buf[1] << 2) & 0xf0;
- alpha = (buf[1] << 6) & 0xc0;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
- buf += 2;
- }
+ if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1)
+ {
+ mprint("More than one bit level marked: %x\n", depth);
+ }
- if (y == 0)
- alpha = 0xff;
-
- YUV_TO_RGB1_CCIR(cb, cr);
- YUV_TO_RGB2_CCIR(r, g, b, y);
-
- printf("clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
- if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
- printf("More than one bit level marked: %x\n", depth);
- }
-
- if (depth & 0x80)
- clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
- else if (depth & 0x40)
- clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
- else if (depth & 0x20)
- clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
- }
- }
- return 0;
+ if (depth & 0x80)
+ clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
+ else if (depth & 0x40)
+ clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
+ else if (depth & 0x20)
+ clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
+ }
+ }
+ return 0;
}
-
-static void dvbsub_parse_region_segment(void*dvb_ctx,
- const uint8_t *buf, int buf_size)
+static void dvbsub_parse_region_segment(void*dvb_ctx, const uint8_t *buf,
+ int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
- const uint8_t *buf_end = buf + buf_size;
- int region_id, object_id;
- int version;
- DVBSubRegion *region;
- DVBSubObject *object;
- DVBSubObjectDisplay *display;
- int fill;
+ const uint8_t *buf_end = buf + buf_size;
+ int region_id, object_id;
+ int version;
+ DVBSubRegion *region;
+ DVBSubObject *object;
+ DVBSubObjectDisplay *display;
+ int fill;
- if (buf_size < 10)
- return;
+ if (buf_size < 10)
+ return;
- region_id = *buf++;
- version = ((*buf)>>4) & 15;
+ region_id = *buf++;
+ version = ((*buf) >> 4) & 15;
- region = get_region(ctx, region_id);
+ region = get_region(ctx, region_id);
- if (!region) {
- region = (struct DVBSubRegion*) malloc(sizeof(struct DVBSubRegion));
- memset(region,0,sizeof(struct DVBSubRegion));
+ if (!region)
+ {
+ region = (struct DVBSubRegion*) malloc(sizeof(struct DVBSubRegion));
+ memset(region, 0, sizeof(struct DVBSubRegion));
- region->id = region_id;
- region->version = version;
+ region->id = region_id;
+ region->version = version;
- region->next = ctx->region_list;
- ctx->region_list = region;
- } else if(version == region->version)
- return;
- fill = ((*buf++) >> 3) & 1;
+ region->next = ctx->region_list;
+ ctx->region_list = region;
+ }
+ else if (version == region->version)
+ return;
+ fill = ((*buf++) >> 3) & 1;
- region->width = RB16(buf);
- buf += 2;
- region->height = RB16(buf);
- buf += 2;
+ region->width = RB16(buf);
+ buf += 2;
+ region->height = RB16(buf);
+ buf += 2;
- if (region->width * region->height != region->buf_size) {
- free(region->pbuf);
+ if (region->width * region->height != region->buf_size)
+ {
+ free(region->pbuf);
- region->buf_size = region->width * region->height;
+ region->buf_size = region->width * region->height;
- region->pbuf = (uint8_t*)malloc(region->buf_size);
+ region->pbuf = (uint8_t*) malloc(region->buf_size);
- fill = 1;
- region->dirty = 0;
- }
+ fill = 1;
+ region->dirty = 0;
+ }
- region->depth = 1 << (((*buf++) >> 2) & 7);
- if(region->depth<2 || region->depth>8){
- printf( "region depth %d is invalid\n", region->depth);
- region->depth= 4;
- }
- region->clut = *buf++;
+ region->depth = 1 << (((*buf++) >> 2) & 7);
+ if (region->depth < 2 || region->depth > 8)
+ {
+ mprint("region depth %d is invalid\n", region->depth);
+ region->depth = 4;
+ }
+ region->clut = *buf++;
- if (region->depth == 8) {
- region->bgcolor = *buf++;
- buf += 1;
- } else {
- buf += 1;
+ if (region->depth == 8)
+ {
+ region->bgcolor = *buf++;
+ buf += 1;
+ }
+ else
+ {
+ buf += 1;
- if (region->depth == 4)
- region->bgcolor = (((*buf++) >> 4) & 15);
- else
- region->bgcolor = (((*buf++) >> 2) & 3);
- }
+ if (region->depth == 4)
+ region->bgcolor = (((*buf++) >> 4) & 15);
+ else
+ region->bgcolor = (((*buf++) >> 2) & 3);
+ }
- printf("Region %d, (%dx%d)\n", region_id, region->width, region->height);
+ if (fill)
+ memset(region->pbuf, region->bgcolor, region->buf_size);
- if (fill) {
- memset(region->pbuf, region->bgcolor, region->buf_size);
- printf( "Fill region (%d)\n", region->bgcolor);
- }
+ delete_region_display_list(ctx, region);
- delete_region_display_list(ctx, region);
+ while (buf + 5 < buf_end)
+ {
+ object_id = RB16(buf);
+ buf += 2;
- while (buf + 5 < buf_end) {
- object_id = RB16(buf);
- buf += 2;
+ object = get_object(ctx, object_id);
- object = get_object(ctx, object_id);
+ if (!object)
+ {
+ object = (struct DVBSubObject*) malloc(sizeof(struct DVBSubObject));
+ memset(object, 0, sizeof(struct DVBSubObject));
- if (!object) {
- object = (struct DVBSubObject*)malloc(sizeof(struct DVBSubObject));
- memset(object,0,sizeof(struct DVBSubObject));
+ object->id = object_id;
+ object->next = ctx->object_list;
+ ctx->object_list = object;
+ }
- object->id = object_id;
- object->next = ctx->object_list;
- ctx->object_list = object;
- }
+ object->type = (*buf) >> 6;
- object->type = (*buf) >> 6;
+ display = (struct DVBSubObjectDisplay*) malloc(
+ sizeof(struct DVBSubObjectDisplay));
+ memset(display, 0, sizeof(struct DVBSubObjectDisplay));
- display = (struct DVBSubObjectDisplay*)malloc(sizeof(struct DVBSubObjectDisplay));
- memset(display,0,sizeof(struct DVBSubObjectDisplay));
+ display->object_id = object_id;
+ display->region_id = region_id;
- display->object_id = object_id;
- display->region_id = region_id;
+ display->x_pos = RB16(buf) & 0xfff;
+ buf += 2;
+ display->y_pos = RB16(buf) & 0xfff;
+ buf += 2;
- display->x_pos = RB16(buf) & 0xfff;
- buf += 2;
- display->y_pos = RB16(buf) & 0xfff;
- buf += 2;
+ if ((object->type == 1 || object->type == 2) && buf + 1 < buf_end)
+ {
+ display->fgcolor = *buf++;
+ display->bgcolor = *buf++;
+ }
- if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
- display->fgcolor = *buf++;
- display->bgcolor = *buf++;
- }
+ display->region_list_next = region->display_list;
+ region->display_list = display;
- display->region_list_next = region->display_list;
- region->display_list = display;
-
- display->object_list_next = object->display_list;
- object->display_list = display;
- }
+ display->object_list_next = object->display_list;
+ object->display_list = display;
+ }
}
-static void dvbsub_parse_page_segment(void *dvb_ctx,
- const uint8_t *buf, int buf_size)
+static void dvbsub_parse_page_segment(void *dvb_ctx, const uint8_t *buf,
+ int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext*)dvb_ctx;
- DVBSubRegionDisplay *display;
- DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
+ DVBSubContext *ctx = (DVBSubContext*) dvb_ctx;
+ DVBSubRegionDisplay *display;
+ DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
- const uint8_t *buf_end = buf + buf_size;
- int region_id;
- int page_state;
- int timeout;
- int version;
+ const uint8_t *buf_end = buf + buf_size;
+ int region_id;
+ int page_state;
+ int timeout;
+ int version;
- if (buf_size < 1)
- return;
+ if (buf_size < 1)
+ return;
- timeout = *buf++;
- version = ((*buf)>>4) & 15;
- page_state = ((*buf++) >> 2) & 3;
+ timeout = *buf++;
+ version = ((*buf) >> 4) & 15;
+ page_state = ((*buf++) >> 2) & 3;
- //if version same mean we are already updated
- if (ctx->version == version)
- {
- return;
- }
+ //if version same mean we are already updated
+ if (ctx->version == version)
+ {
+ return;
+ }
- ctx->time_out = timeout;
- ctx->version = version;
+ ctx->time_out = timeout;
+ ctx->version = version;
- printf( "Page time out %ds, state %d\n", ctx->time_out, page_state);
+ if (page_state == 1 || page_state == 2)
+ {
+ delete_regions(ctx);
+ delete_objects(ctx);
+ delete_cluts(ctx);
+ }
- if (page_state == 1 || page_state == 2) {
- delete_regions(ctx);
- delete_objects(ctx);
- delete_cluts(ctx);
- }
+ tmp_display_list = ctx->display_list;
+ ctx->display_list = NULL;
- tmp_display_list = ctx->display_list;
- ctx->display_list = NULL;
+ while (buf + 5 < buf_end)
+ {
+ region_id = *buf++;
+ buf += 1;
- while (buf + 5 < buf_end) {
- region_id = *buf++;
- buf += 1;
+ display = tmp_display_list;
+ tmp_ptr = &tmp_display_list;
- display = tmp_display_list;
- tmp_ptr = &tmp_display_list;
+ while (display && display->region_id != region_id)
+ {
+ tmp_ptr = &display->next;
+ display = display->next;
+ }
- while (display && display->region_id != region_id) {
- tmp_ptr = &display->next;
- display = display->next;
- }
+ if (!display)
+ {
+ display = (struct DVBSubRegionDisplay*) malloc(
+ sizeof(struct DVBSubRegionDisplay));
+ memset(display, 0, sizeof(struct DVBSubRegionDisplay));
+ }
- if (!display)
- {
- display = (struct DVBSubRegionDisplay*)malloc(sizeof(struct DVBSubRegionDisplay));
- memset(display,0,sizeof(struct DVBSubRegionDisplay));
- }
+ display->region_id = region_id;
+ display->x_pos = RB16(buf);
+ buf += 2;
+ display->y_pos = RB16(buf);
+ buf += 2;
- display->region_id = region_id;
+ *tmp_ptr = display->next;
- display->x_pos = RB16(buf);
- buf += 2;
- display->y_pos = RB16(buf);
- buf += 2;
+ display->next = ctx->display_list;
+ ctx->display_list = display;
- *tmp_ptr = display->next;
+ }
- display->next = ctx->display_list;
- ctx->display_list = display;
+ while (tmp_display_list)
+ {
+ display = tmp_display_list;
- printf( "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
- }
+ tmp_display_list = display->next;
- while (tmp_display_list) {
- display = tmp_display_list;
-
- tmp_display_list = display->next;
-
- free(display);
- }
+ free(display);
+ }
}
-
#ifdef DEBUG
static void save_display_set(DVBSubContext *ctx)
{
- DVBSubRegion *region;
- DVBSubRegionDisplay *display;
- DVBSubCLUT *clut;
- uint32_t *clut_table;
- int x_pos, y_pos, width, height;
- int x, y, y_off, x_off;
- uint32_t *pbuf;
- char filename[32];
- static int fileno_index = 0;
+ DVBSubRegion *region;
+ DVBSubRegionDisplay *display;
+ DVBSubCLUT *clut;
+ uint32_t *clut_table;
+ int x_pos, y_pos, width, height;
+ int x, y, y_off, x_off;
+ uint32_t *pbuf;
+ char *filename;
+ void *sp = ctx->out->spupng_data;
+ long long start = get_visible_start();
+ x_pos = -1;
+ y_pos = -1;
+ width = 0;
+ height = 0;
- x_pos = -1;
- y_pos = -1;
- width = 0;
- height = 0;
+ filename = get_spupng_filename(sp);
+ inc_spupng_fileindex(sp);
+ write_sputag(sp, start, start + ctx->time_out);
+ for (display = ctx->display_list; display; display = display->next)
+ {
+ region = get_region(ctx, display->region_id);
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
+ if (x_pos == -1)
+ {
+ x_pos = display->x_pos;
+ y_pos = display->y_pos;
+ width = region->width;
+ height = region->height;
+ }
+ else
+ {
+ if (display->x_pos < x_pos)
+ {
+ width += (x_pos - display->x_pos);
+ x_pos = display->x_pos;
+ }
- if (x_pos == -1) {
- x_pos = display->x_pos;
- y_pos = display->y_pos;
- width = region->width;
- height = region->height;
- } else {
- if (display->x_pos < x_pos) {
- width += (x_pos - display->x_pos);
- x_pos = display->x_pos;
- }
+ if (display->y_pos < y_pos)
+ {
+ height += (y_pos - display->y_pos);
+ y_pos = display->y_pos;
+ }
- if (display->y_pos < y_pos) {
- height += (y_pos - display->y_pos);
- y_pos = display->y_pos;
- }
+ if (display->x_pos + region->width > x_pos + width)
+ {
+ width = display->x_pos + region->width - x_pos;
+ }
- if (display->x_pos + region->width > x_pos + width) {
- width = display->x_pos + region->width - x_pos;
- }
+ if (display->y_pos + region->height > y_pos + height)
+ {
+ height = display->y_pos + region->height - y_pos;
+ }
+ }
+ }
- if (display->y_pos + region->height > y_pos + height) {
- height = display->y_pos + region->height - y_pos;
- }
- }
- }
+ if (x_pos >= 0)
+ {
- if (x_pos >= 0) {
+ pbuf = (uint32_t*) malloc(width * height * 4);
+ memset(pbuf, 0x0, width * height * 4);
- pbuf = (uint32_t*)malloc(width * height * 4);
- memset(pbuf,0x0,width * height * 4);
+ for (display = ctx->display_list; display; display = display->next)
+ {
+ region = get_region(ctx, display->region_id);
+ x_off = display->x_pos - x_pos;
+ y_off = display->y_pos - y_pos;
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
+ clut = get_clut(ctx, region->clut);
- x_off = display->x_pos - x_pos;
- y_off = display->y_pos - y_pos;
+ if (clut == 0)
+ clut = &default_clut;
- clut = get_clut(ctx, region->clut);
+ switch (region->depth)
+ {
+ case 2:
+ clut_table = clut->clut4;
+ break;
+ case 8:
+ clut_table = clut->clut256;
+ break;
+ case 4:
+ default:
+ clut_table = clut->clut16;
+ break;
+ }
- if (clut == 0)
- clut = &default_clut;
+ for (y = 0; y < region->height; y++)
+ {
+ for (x = 0; x < region->width; x++)
+ {
+ pbuf[((y + y_off) * width) + x_off + x] =
+ clut_table[region->pbuf[y * region->width + x]];
+ }
+ }
- switch (region->depth) {
- case 2:
- clut_table = clut->clut4;
- break;
- case 8:
- clut_table = clut->clut256;
- break;
- case 4:
- default:
- clut_table = clut->clut16;
- break;
- }
+ }
- for (y = 0; y < region->height; y++) {
- for (x = 0; x < region->width; x++) {
- pbuf[((y + y_off) * width) + x_off + x] =
- clut_table[region->pbuf[y * region->width + x]];
- }
- }
+ png_save(filename, pbuf, width, height);
+ //png_save1(filename, region->pbuf, region->width, region->height,clut->clut16);
- }
+ free(pbuf);
+ }
- snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
-
- png_save(filename, pbuf, width, height);
-
- free(pbuf);
- }
-
- fileno_index++;
}
#endif
static void dvbsub_parse_display_definition_segment(void *dvb_ctx,
- const uint8_t *buf,
- int buf_size)
+ const uint8_t *buf, int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
- DVBSubDisplayDefinition *display_def = ctx->display_definition;
- int dds_version, info_byte;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
+ DVBSubDisplayDefinition *display_def = ctx->display_definition;
+ int dds_version, info_byte;
- if (buf_size < 5)
- return;
+ if (buf_size < 5)
+ return;
- info_byte = bytestream_get_byte(&buf);
- dds_version = info_byte >> 4;
- if (display_def && display_def->version == dds_version)
- return; // already have this display definition version
+ info_byte = bytestream_get_byte(&buf);
+ dds_version = info_byte >> 4;
+ if (display_def && display_def->version == dds_version)
+ return; // already have this display definition version
- if (!display_def) {
- display_def = (struct DVBSubDisplayDefinition*)malloc(sizeof(*display_def));
- memset(display_def,0,sizeof(*display_def));
- ctx->display_definition = display_def;
- }
- if (!display_def)
- return;
+ if (!display_def)
+ {
+ display_def = (struct DVBSubDisplayDefinition*) malloc(
+ sizeof(*display_def));
+ memset(display_def, 0, sizeof(*display_def));
+ ctx->display_definition = display_def;
+ }
+ if (!display_def)
+ return;
- display_def->version = dds_version;
- display_def->x = 0;
- display_def->y = 0;
- display_def->width = bytestream_get_be16(&buf) + 1;
- display_def->height = bytestream_get_be16(&buf) + 1;
+ display_def->version = dds_version;
+ display_def->x = 0;
+ display_def->y = 0;
+ display_def->width = bytestream_get_be16(&buf) + 1;
+ display_def->height = bytestream_get_be16(&buf) + 1;
- if (buf_size < 13)
- return;
+ if (buf_size < 13)
+ return;
- if (info_byte & 1<<3) { // display_window_flag
- display_def->x = bytestream_get_be16(&buf);
- display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
- display_def->y = bytestream_get_be16(&buf);
- display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
- }
+ if (info_byte & 1 << 3)
+ { // display_window_flag
+ display_def->x = bytestream_get_be16(&buf);
+ display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
+ display_def->y = bytestream_get_be16(&buf);
+ display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
+ }
}
static int dvbsub_display_end_segment(void *dvb_ctx, const uint8_t *buf,
- int buf_size)
+ int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
- DVBSubRegion *region;
- DVBSubRegionDisplay *display;
- DVBSubCLUT *clut;
- int i;
+ DVBSubRegion *region;
+ DVBSubRegionDisplay *display;
+ DVBSubCLUT *clut;
+ int i;
+ for (display = ctx->display_list; display; display = display->next)
+ {
+ region = get_region(ctx, display->region_id);
+ }
+ i = 0;
- for (display = ctx->display_list; display; display = display->next)
- {
- region = get_region(ctx, display->region_id);
- }
+ for (display = ctx->display_list; display; display = display->next)
+ {
+ region = get_region(ctx, display->region_id);
- i = 0;
+ if (!region)
+ continue;
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
+ if (!region->dirty)
+ continue;
+ clut = get_clut(ctx, region->clut);
- if (!region)
- continue;
+ if (!clut)
+ clut = &default_clut;
- if (!region->dirty)
- continue;
- clut = get_clut(ctx, region->clut);
-
- if (!clut)
- clut = &default_clut;
-
- i++;
- }
+ i++;
+ }
#ifdef DEBUG
- save_display_set(ctx);
+ if (ctx->object_list)
+ {
+ save_display_set(ctx);
+ }
#endif
- return 1;
+ return 1;
}
/**
* @param dvb_ctx PreInitialized DVB context using DVB
* @param data output subtitle data, to be implemented
- * @param data_size Output subtitle data size. pass the pointer to an intiger, NOT to be NULL.
- * @param buf buffer containg segment data, first sync byte needto 0x0f.
+ * @param data_size Output subtitle data size. pass the pointer to an integer, NOT to be NULL.
+ * @param buf buffer containing segment data, first sync byte need to 0x0f.
* does not include data_identifier and subtitle_stream_id.
* @param buf_size size of buf buffer
*
* @return -1 on error
*/
-int dvbsub_decode(void *dvb_ctx,
- void *data, int *data_size,
- const unsigned char *buf, int buf_size)
+int dvbsub_decode(void *dvb_ctx, void *data, int *data_size,
+ const unsigned char *buf, int buf_size)
{
- DVBSubContext *ctx = (DVBSubContext *)dvb_ctx;
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
// AVSubtitle *sub = data;
- const uint8_t *p, *p_end;
- int segment_type;
- int page_id;
- int segment_length;
- int ret;
- int got_segment = 0;
+ const uint8_t *p, *p_end;
+ int segment_type;
+ int page_id;
+ int segment_length;
+ int ret;
+ int got_segment = 0;
+ if (buf_size <= 6 || *buf != 0x0f)
+ {
+ mprint("incomplete or broken packet");
+ return -1;
+ }
- if (buf_size <= 6 || *buf != 0x0f) {
- printf( "incomplete or broken packet");
- return -1;
- }
+ p = buf;
+ p_end = buf + buf_size;
- p = buf;
- p_end = buf + buf_size;
+ while (p_end - p >= 6 && *p == 0x0f)
+ {
+ p += 1;
+ segment_type = *p++;
+ page_id = RB16(p);
+ p += 2;
+ segment_length = RB16(p);
+ p += 2;
- while (p_end - p >= 6 && *p == 0x0f) {
- p += 1;
- segment_type = *p++;
- page_id = RB16(p);
- p += 2;
- segment_length = RB16(p);
- p += 2;
+ if (p_end - p < segment_length)
+ {
+ mprint("incomplete or broken packet");
+ return -1;
+ }
- if (p_end - p < segment_length) {
- printf( "incomplete or broken packet");
- return -1;
- }
+ if (page_id == ctx->composition_id || page_id == ctx->ancillary_id
+ || ctx->composition_id == -1 || ctx->ancillary_id == -1)
+ {
+ switch (segment_type)
+ {
+ case DVBSUB_PAGE_SEGMENT:
+ dvbsub_parse_page_segment(dvb_ctx, p, segment_length);
+ got_segment |= 1;
+ break;
+ case DVBSUB_REGION_SEGMENT:
+ dvbsub_parse_region_segment(dvb_ctx, p, segment_length);
+ got_segment |= 2;
+ break;
+ case DVBSUB_CLUT_SEGMENT:
+ ret = dvbsub_parse_clut_segment(dvb_ctx, p, segment_length);
+ if (ret < 0)
+ return ret;
+ got_segment |= 4;
+ break;
+ case DVBSUB_OBJECT_SEGMENT:
+ dvbsub_parse_object_segment(dvb_ctx, p, segment_length);
+ got_segment |= 8;
+ break;
+ case DVBSUB_DISPLAYDEFINITION_SEGMENT:
+ dvbsub_parse_display_definition_segment(dvb_ctx, p,
+ segment_length);
+ break;
+ case DVBSUB_DISPLAY_SEGMENT:
+ *data_size = dvbsub_display_end_segment(dvb_ctx, p,
+ segment_length);
+ got_segment |= 16;
+ break;
+ default:
+ mprint(
+ "Subtitling segment type 0x%x, page id %d, length %d\n",
+ segment_type, page_id, segment_length);
+ break;
+ }
+ }
- if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
- ctx->composition_id == -1 || ctx->ancillary_id == -1) {
- switch (segment_type) {
- case DVBSUB_PAGE_SEGMENT:
- dvbsub_parse_page_segment(dvb_ctx, p, segment_length);
- got_segment |= 1;
- break;
- case DVBSUB_REGION_SEGMENT:
- dvbsub_parse_region_segment(dvb_ctx, p, segment_length);
- got_segment |= 2;
- break;
- case DVBSUB_CLUT_SEGMENT:
- ret = dvbsub_parse_clut_segment(dvb_ctx, p, segment_length);
- if (ret < 0) return ret;
- got_segment |= 4;
- break;
- case DVBSUB_OBJECT_SEGMENT:
- dvbsub_parse_object_segment(dvb_ctx, p, segment_length);
- got_segment |= 8;
- break;
- case DVBSUB_DISPLAYDEFINITION_SEGMENT:
- dvbsub_parse_display_definition_segment(dvb_ctx, p, segment_length);
- break;
- case DVBSUB_DISPLAY_SEGMENT:
- *data_size = dvbsub_display_end_segment(dvb_ctx, p, segment_length);
- got_segment |= 16;
- break;
- default:
- printf( "Subtitling segment type 0x%x, page id %d, length %d\n",
- segment_type, page_id, segment_length);
- break;
- }
- }
+ p += segment_length;
+ }
+ // Some streams do not send a display segment but if we have all the other
+ // segments then we need no further data.
+ if (got_segment == 15)
+ *data_size = dvbsub_display_end_segment(dvb_ctx, p, 0);
- p += segment_length;
- }
- // Some streams do not send a display segment but if we have all the other
- // segments then we need no further data.
- if (got_segment == 15)
- *data_size = dvbsub_display_end_segment(dvb_ctx, p, 0);
-
- return p - buf;
+ return p - buf;
}
/**
* @func parse_dvb_description
@@ -1645,50 +1888,63 @@ int dvbsub_decode(void *dvb_ctx,
* @return return -1 if invalid data found other wise 0 if everything goes well
* errno is set is to EINVAL if invalid data is found
*/
-int parse_dvb_description (struct dvb_config* cfg,unsigned char*data,unsigned int len)
+int parse_dvb_description(struct dvb_config* cfg, unsigned char*data,
+ unsigned int len)
{
- int i = 0;
- int j = 0;
- /* 8 bytes per DVB subtitle substream d2:
- * ISO_639_language_code (3 bytes),
- * subtitling_type (1 byte),
- * composition_page_id (2 bytes),
- * ancillary_page_id (2 bytes)
- */
+ int i = 0;
+ int j = 0;
+ /* 8 bytes per DVB subtitle substream d2:
+ * ISO_639_language_code (3 bytes),
+ * subtitling_type (1 byte),
+ * composition_page_id (2 bytes),
+ * ancillary_page_id (2 bytes)
+ */
- cfg->n_language = len/8;
+ cfg->n_language = len / 8;
- if (len > 0 && len % 8 != 0)
- {
- errno = EINVAL;
- return -1;
- }
+ if (len > 0 && len % 8 != 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
- if (cfg->n_language > 1)
- {
- printf("DVB subtitles with multiple languages");
- }
+ if (cfg->n_language > 1)
+ {
+ mprint("DVB subtitles with multiple languages");
+ }
- if (cfg->n_language > MAX_LANGUAGE_PER_DESC)
- {
- printf("not supported more then %d language",MAX_LANGUAGE_PER_DESC);
- }
+ if (cfg->n_language > MAX_LANGUAGE_PER_DESC)
+ {
+ mprint("not supported more then %d language", MAX_LANGUAGE_PER_DESC);
+ }
- for (i = 0; i < cfg->n_language; i++,data += i*8)
- {
- /* setting language to undefined if not found in language lkup table */
- for(j = 0,cfg->lang_index[i] = 0;dvb_language[j] != NULL;j++)
- {
- if(!strncmp((const char*)(data),dvb_language[j],3))
- cfg->lang_index[i] = j;
- }
- cfg->sub_type[i] = data[3];
- cfg->composition_id[i] = RB16(data + 4);
- cfg->ancillary_id[i] = RB16(data + 6);
+ for (i = 0; i < cfg->n_language; i++, data += i * 8)
+ {
+ /* setting language to undefined if not found in language lkup table */
+ for (j = 0, cfg->lang_index[i] = 0; dvb_language[j] != NULL ; j++)
+ {
+ if (!strncmp((const char*) (data), dvb_language[j], 3))
+ cfg->lang_index[i] = j;
+ }
+ cfg->sub_type[i] = data[3];
+ cfg->composition_id[i] = RB16(data + 4);
+ cfg->ancillary_id[i] = RB16(data + 6);
- }
+ }
- printf("lang %d %s\n",cfg->lang_index[0],dvb_language[cfg->lang_index[0]]);
- printf("comp %hd anci %hd stype %hhd\n",cfg->composition_id[0],cfg->ancillary_id[0],cfg->sub_type[0]);
- return 0;
+ return 0;
+}
+/*
+ * @func dvbsub_set_write the output structure in dvb
+ * set ccx_s_write structure in dvb_ctx
+ *
+ * @param dvb_ctx context of dvb which was returned by dvbsub_init_decoder
+ *
+ * @param out output context returned by init_write
+ *
+ */
+void dvbsub_set_write(void *dvb_ctx, struct ccx_s_write *out)
+{
+ DVBSubContext *ctx = (DVBSubContext *) dvb_ctx;
+ ctx->out = out;
}
diff --git a/src/dvb_subtitle_decoder.h b/src/dvb_subtitle_decoder.h
index 9f53cc39..ed0f4e19 100644
--- a/src/dvb_subtitle_decoder.h
+++ b/src/dvb_subtitle_decoder.h
@@ -18,6 +18,7 @@
#define MAX_LANGUAGE_PER_DESC 5
+#include "ccextractor.h"
#ifdef __cplusplus
extern "C"
{
@@ -25,17 +26,16 @@ extern "C"
struct dvb_config
{
- unsigned char n_language;
- unsigned int lang_index[MAX_LANGUAGE_PER_DESC];
- /* subtitle type */
- unsigned char sub_type[MAX_LANGUAGE_PER_DESC];
- /* composition page id */
- unsigned short composition_id[MAX_LANGUAGE_PER_DESC];
- /* ancillary_page_id */
- unsigned short ancillary_id[MAX_LANGUAGE_PER_DESC];
+ unsigned char n_language;
+ unsigned int lang_index[MAX_LANGUAGE_PER_DESC];
+ /* subtitle type */
+ unsigned char sub_type[MAX_LANGUAGE_PER_DESC];
+ /* composition page id */
+ unsigned short composition_id[MAX_LANGUAGE_PER_DESC];
+ /* ancillary_page_id */
+ unsigned short ancillary_id[MAX_LANGUAGE_PER_DESC];
};
-
/**
* @param composition_id composition-page_id found in Subtitle descriptors
* associated with subtitle stream in the PMT
@@ -47,7 +47,7 @@ struct dvb_config
* @return DVB context kept as void* for abstraction
*
*/
-void* dvbsub_init_decoder(int composition_id,int ancillary_id);
+void* dvbsub_init_decoder(int composition_id, int ancillary_id);
int dvbsub_close_decoder(void *dvb_ctx);
@@ -61,9 +61,8 @@ int dvbsub_close_decoder(void *dvb_ctx);
*
* @return -1 on error
*/
-int dvbsub_decode(void *dvb_ctx,
- void *data, int *data_size,
- const unsigned char *buf,int buf_size);
+int dvbsub_decode(void *dvb_ctx, void *data, int *data_size,
+ const unsigned char *buf, int buf_size);
/**
* @func parse_dvb_description
*
@@ -74,8 +73,19 @@ int dvbsub_decode(void *dvb_ctx,
* @return return -1 if invalid data found other wise 0 if everything goes well
* errno is set is to EINVAL if invalid data is found
*/
-int parse_dvb_description (struct dvb_config* cfg,unsigned char*data,unsigned int len);
+int parse_dvb_description(struct dvb_config* cfg, unsigned char*data,
+ unsigned int len);
+/*
+ * @func dvbsub_set_write the output structure in dvb
+ * set ccx_s_write structure in dvb_ctx
+ *
+ * @param dvb_ctx context of dvb which was returned by dvbsub_init_decoder
+ *
+ * @param out output context returned by init_write
+ *
+ */
+void dvbsub_set_write(void *dvb_ctx, struct ccx_s_write *out);
#ifdef __cplusplus
}
#endif
diff --git a/src/spupng_encoder.c b/src/spupng_encoder.c
index bf30cf85..7b68a073 100644
--- a/src/spupng_encoder.c
+++ b/src/spupng_encoder.c
@@ -292,3 +292,38 @@ void draw_char_indexed(uint8_t * canvas, int rowstride, uint8_t * pen,
unicode_ccfont2(unicode, italic),
underline * (3 << 24) /* cell row 24, 25 */);
}
+
+void write_sputag(struct spupng_t *sp,LLONG ms_start,LLONG ms_end)
+{
+ fprintf(sp->fpxml, "fpxml, " end=\"%.3f\"", ((double)ms_end) / 1000);
+ fprintf(sp->fpxml, " image=\"%s\"", sp->pngfile);
+ fprintf(sp->fpxml, " xoffset=\"%d\"", sp->xOffset);
+ fprintf(sp->fpxml, " yoffset=\"%d\"", sp->yOffset);
+ fprintf(sp->fpxml, ">\n");
+ fprintf(sp->fpxml, "\n");
+
+}
+void write_spucomment(struct spupng_t *sp,const char *str)
+{
+ fprintf(sp->fpxml, "\n");
+}
+
+int get_spupng_subtype(void)
+{
+ return (1 << CCX_OF_TYPE_TEXT)|(1<pngfile, "%s/sub%04d.png", sp->dirname, sp->fileIndex);
+ return sp->pngfile;
+}
+void inc_spupng_fileindex(void *ctx)
+{
+ struct spupng_t *sp = (struct spupng_t *)ctx;
+ sp->fileIndex++;
+}
+
diff --git a/src/spupng_encoder.h b/src/spupng_encoder.h
index 29ba7fa4..13576089 100644
--- a/src/spupng_encoder.h
+++ b/src/spupng_encoder.h
@@ -27,4 +27,8 @@ void write_spumux_header(struct ccx_s_write *out);
void write_spumux_footer(struct ccx_s_write *out);
void draw_char_indexed(uint8_t * canvas, int rowstride, uint8_t * pen,
int unicode, int italic, int underline);
+void write_sputag(struct spupng_t *sp,LLONG ms_start,LLONG ms_end);
+void write_spucomment(struct spupng_t *sp,const char *str);
+char* get_spupng_filename(void *ctx);
+void inc_spupng_fileindex(void *ctx);
#endif
diff --git a/src/stream_functions.c b/src/stream_functions.c
index 267a5535..b25cb1c9 100644
--- a/src/stream_functions.c
+++ b/src/stream_functions.c
@@ -171,6 +171,40 @@ int detect_myth( void )
return 0;
}
+int read_pts_pes(unsigned char*header, int len)
+{
+ unsigned int peslen = 0;
+ LLONG bits_9;
+ unsigned int bits_10;
+ unsigned int bits_11;
+ unsigned int bits_12;
+ unsigned int bits_13;
+
+ //function used only to set start time
+ if(pts_set)
+ return -1;
+ //it might not be pes packet
+ if (!(header[0] == 0 && header[1] == 0 && header[2] == 1))
+ return -1;
+
+
+ peslen = header[4] << 8 | header[5];
+
+ if (header[7] & 0x80)
+ {
+ bits_9 = ((LLONG) header[9] & 0x0E) << 29; // PTS 32..30 - Must be LLONG to prevent overflow
+ bits_10 = header[10] << 22; // PTS 29..22
+ bits_11 = (header[11] & 0xFE) << 14; // PTS 21..15
+ bits_12 = header[12] << 7; // PTS 14-7
+ bits_13 = header[13] >> 1; // PTS 6-0
+ }
+ else
+ return -1;
+ current_pts = bits_9 | bits_10 | bits_11 | bits_12 | bits_13;
+ pts_set = 1;
+
+ return 0;
+}
/* Read and evaluate the current video PES header. The function returns
* the length of the payload if successful, otherwise -1 is returned
diff --git a/src/ts_functions.c b/src/ts_functions.c
index c642d051..6cb715c0 100644
--- a/src/ts_functions.c
+++ b/src/ts_functions.c
@@ -366,6 +366,15 @@ long ts_readstream(void)
haup_capbuflen = haup_newcapbuflen;
}
+ /*
+ * if dvb subtitle is selected then start time taken from first PTS
+ * of any stream
+ */
+ if ( cap_stream_type == CCX_STREAM_TYPE_PRIVATE_MPEG2 && cxx_dvb_context && !pts_set)
+ {
+ if(read_pts_pes(payload.start,payload.length) == 0)
+ set_fts();
+ }
// Check for PID with captions. Note that in Hauppauge mode we also process the video stream because
// we need the timing from its PES header, which isn't included in Hauppauge's packets
diff --git a/src/ts_tables.c b/src/ts_tables.c
index 9ccfe863..bb65daab 100644
--- a/src/ts_tables.c
+++ b/src/ts_tables.c
@@ -210,13 +210,21 @@ int parse_PMT (int pos)
ccx_options.ts_cappid = newcappid = elementary_PID;
cap_stream_type=CCX_STREAM_TYPE_UNKNOWNSTREAM;
}
- if(IS_FEASIBLE(ccx_options.codec,ccx_options.nocodec,CCX_CODEC_DVB) && !ccx_options.ts_cappid && ccx_stream_type == CCX_STREAM_TYPE_PRIVATE_MPEG2)
+ if(IS_FEASIBLE(ccx_options.codec,ccx_options.nocodec,CCX_CODEC_DVB) &&
+ !ccx_options.ts_cappid &&
+ ccx_stream_type == CCX_STREAM_TYPE_PRIVATE_MPEG2 &&
+ ES_info_length )
{
unsigned char *es_info = payload_start + i + 5;
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) - es_info ;es_info += desc_len)
{
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
desc_len = (*es_info++);
+ if(ccx_options.write_format != CCX_OF_SPUPNG )
+ {
+ mprint ("DVB subtitle only support spupng type as output\n");
+ continue;
+ }
if(CCX_MPEG_DSC_DVB_SUBTITLE == descriptor_tag)
{
struct dvb_config cnf;
@@ -227,6 +235,7 @@ int parse_PMT (int pos)
cxx_dvb_context = dvbsub_init_decoder(cnf.composition_id[0],cnf.ancillary_id[0]);
if (cxx_dvb_context == NULL)
break;
+ dvbsub_set_write(cxx_dvb_context,&wbout1);
ccx_options.ts_cappid = newcappid = elementary_PID;
cap_stream_type = newcap_stream_type = ccx_stream_type;
}