| Index: source/patched-ffmpeg-mt/libavcodec/dvbsubdec.c
|
| ===================================================================
|
| --- source/patched-ffmpeg-mt/libavcodec/dvbsubdec.c (revision 50820)
|
| +++ source/patched-ffmpeg-mt/libavcodec/dvbsubdec.c (working copy)
|
| @@ -22,6 +22,7 @@
|
| #include "dsputil.h"
|
| #include "get_bits.h"
|
| #include "colorspace.h"
|
| +#include "bytestream.h"
|
|
|
| //#define DEBUG
|
| //#define DEBUG_PACKET_CONTENTS
|
| @@ -31,6 +32,7 @@
|
| #define DVBSUB_REGION_SEGMENT 0x11
|
| #define DVBSUB_CLUT_SEGMENT 0x12
|
| #define DVBSUB_OBJECT_SEGMENT 0x13
|
| +#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
|
| #define DVBSUB_DISPLAY_SEGMENT 0x80
|
|
|
| #define cm (ff_cropTbl + MAX_NEG_CROP)
|
| @@ -216,6 +218,15 @@
|
| struct DVBSubRegion *next;
|
| } DVBSubRegion;
|
|
|
| +typedef struct DVBSubDisplayDefinition {
|
| + int version;
|
| +
|
| + int x;
|
| + int y;
|
| + int width;
|
| + int height;
|
| +} DVBSubDisplayDefinition;
|
| +
|
| typedef struct DVBSubContext {
|
| int composition_id;
|
| int ancillary_id;
|
| @@ -227,6 +238,7 @@
|
|
|
| int display_list_size;
|
| DVBSubRegionDisplay *display_list;
|
| + DVBSubDisplayDefinition *display_definition;
|
| } DVBSubContext;
|
|
|
|
|
| @@ -334,6 +346,8 @@
|
| av_free(clut);
|
| }
|
|
|
| + av_freep(&ctx->display_definition);
|
| +
|
| /* Should already be null */
|
| if (ctx->object_list)
|
| av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
|
| @@ -1254,10 +1268,51 @@
|
| }
|
| #endif
|
|
|
| +static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
|
| + const uint8_t *buf,
|
| + int buf_size)
|
| +{
|
| + DVBSubContext *ctx = avctx->priv_data;
|
| + DVBSubDisplayDefinition *display_def = ctx->display_definition;
|
| + int dds_version, info_byte;
|
| +
|
| + 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
|
| +
|
| + if (!display_def) {
|
| + display_def = av_mallocz(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;
|
| +
|
| + if (buf_size < 13)
|
| + return;
|
| +
|
| + if (info_byte & 1<<3) { // display_window_flag
|
| + display_def->x = bytestream_get_be16(&buf);
|
| + display_def->y = bytestream_get_be16(&buf);
|
| + display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
|
| + display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
|
| + }
|
| +}
|
| +
|
| static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
|
| int buf_size, AVSubtitle *sub)
|
| {
|
| DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data;
|
| + DVBSubDisplayDefinition *display_def = ctx->display_definition;
|
|
|
| DVBSubRegion *region;
|
| DVBSubRegionDisplay *display;
|
| @@ -1265,12 +1320,18 @@
|
| DVBSubCLUT *clut;
|
| uint32_t *clut_table;
|
| int i;
|
| + int offset_x=0, offset_y=0;
|
|
|
| sub->rects = NULL;
|
| sub->start_display_time = 0;
|
| sub->end_display_time = ctx->time_out * 1000;
|
| sub->format = 0;
|
|
|
| + if (display_def) {
|
| + offset_x = display_def->x;
|
| + offset_y = display_def->y;
|
| + }
|
| +
|
| sub->num_rects = ctx->display_list_size;
|
|
|
| if (sub->num_rects > 0){
|
| @@ -1288,8 +1349,8 @@
|
| if (!region)
|
| continue;
|
|
|
| - rect->x = display->x_pos;
|
| - rect->y = display->y_pos;
|
| + rect->x = display->x_pos + offset_x;
|
| + rect->y = display->y_pos + offset_y;
|
| rect->w = region->width;
|
| rect->h = region->height;
|
| rect->nb_colors = 16;
|
| @@ -1389,6 +1450,8 @@
|
| case DVBSUB_OBJECT_SEGMENT:
|
| dvbsub_parse_object_segment(avctx, p, segment_length);
|
| break;
|
| + case DVBSUB_DISPLAYDEFINITION_SEGMENT:
|
| + dvbsub_parse_display_definition_segment(avctx, p, segment_length);
|
| case DVBSUB_DISPLAY_SEGMENT:
|
| *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
|
| break;
|
|
|