Fixed huge memory leak related to OCR init

This commit is contained in:
AlexBratosin2001 2017-01-28 22:20:08 +02:00
parent b3010afba7
commit c5ea59aeb1
6 changed files with 175 additions and 164 deletions

View File

@ -302,6 +302,14 @@ struct ccx_demuxer *init_demuxer(void *parent, struct demuxer_cfg *cfg)
ctx->nb_program = 0;
ctx->multi_stream_per_prog = 0;
for (int i = 0; i < MAX_PROGRAM; i++)
{
ctx->pinfo[i].has_all_min_pts = 0;
memset(ctx->pinfo[i].got_important_streams_min_pts, UINT64_MAX, COUNT * sizeof(uint64_t));
ctx->pinfo[i].initialized_ocr = 0;
memset(ctx->pinfo[i].got_important_streams_min_pts, UINT64_MAX, COUNT * sizeof(uint64_t));
}
if(cfg->ts_forced_program != -1)
{
ctx->pinfo[ctx->nb_program].pid = CCX_UNKNOWN;

View File

@ -35,6 +35,7 @@ struct program_info
{
int pid;
int program_number;
int initialized_ocr; // Avoid initializing the OCR more than once
uint8_t analysed_PMT_once:1;
uint8_t version;
uint8_t saved_section[1021];

View File

@ -86,99 +86,6 @@ const uint8_t crop_tab[256 + 2 * MAX_NEG_CROP] = { times256(0x00), 0x00, 0x01,
#define cm (crop_tab + MAX_NEG_CROP)
static __inline unsigned int bytestream_get_byte(const uint8_t **b)
{
(*b) += 1;
return ((const uint8_t*) (*b - 1))[0];
}
static __inline unsigned int bytestream_get_be16(const uint8_t **b)
{
(*b) += 2;
return RB16(*b - 2);
}
typedef struct GetBitContext
{
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
} GetBitContext;
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static __inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
{
int buffer_size;
int ret = 0;
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;
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;
}
static __inline int get_bits_count(const GetBitContext *s)
{
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;
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);
re_index = (
(re_size_plus8 < re_index + (n)) ?
(re_size_plus8) : (re_index + (n)));
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];
result <<= index & 7;
result >>= 8 - 1;
if (s->index < s->size_in_bits_plus8)
index++;
s->index = index;
return result;
}
#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
typedef struct DVBSubCLUT
@ -284,6 +191,100 @@ typedef struct DVBSubContext
DVBSubDisplayDefinition *display_definition;
} DVBSubContext;
static __inline unsigned int bytestream_get_byte(const uint8_t **b)
{
(*b) += 1;
return ((const uint8_t*) (*b - 1))[0];
}
static __inline unsigned int bytestream_get_be16(const uint8_t **b)
{
(*b) += 2;
return RB16(*b - 2);
}
typedef struct GetBitContext
{
const uint8_t *buffer, *buffer_end;
int index;
int size_in_bits;
int size_in_bits_plus8;
} GetBitContext;
/**
* Initialize GetBitContext.
* @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes
* larger than the actual read bits because some optimized bitstream
* readers read 32 or 64 bit at once and could read over the end
* @param bit_size the size of the buffer in bits
* @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow.
*/
static __inline int init_get_bits(GetBitContext *s, const uint8_t *buffer,
int bit_size)
{
int buffer_size;
int ret = 0;
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;
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;
}
static __inline int get_bits_count(const GetBitContext *s)
{
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;
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);
re_index = (
(re_size_plus8 < re_index + (n)) ?
(re_size_plus8) : (re_index + (n)));
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];
result <<= index & 7;
result >>= 8 - 1;
if (s->index < s->size_in_bits_plus8)
index++;
s->index = index;
return result;
}
static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
{
DVBSubObject *ptr = ctx->object_list;
@ -423,7 +424,7 @@ static void delete_regions(DVBSubContext *ctx)
* @return DVB context kept as void* for abstraction
*
*/
void* dvbsub_init_decoder(struct dvb_config* cfg)
void* dvbsub_init_decoder(struct dvb_config* cfg, int initialized_ocr)
{
int i, r, g, b, a = 0;
DVBSubContext *ctx = (DVBSubContext*) malloc(sizeof(DVBSubContext));
@ -443,7 +444,8 @@ void* dvbsub_init_decoder(struct dvb_config* cfg)
}
#ifdef ENABLE_OCR
ctx->ocr_ctx = init_ocr(ctx->lang_index);
if (!initialized_ocr)
ctx->ocr_ctx = init_ocr(ctx->lang_index);
#endif
ctx->version = -1;

View File

@ -1,17 +1,17 @@
/*
* DVB subtitle decoding
* Copyright (c) 2014 Anshul
* License: LGPL
*
* This file is part of CCEXtractor
* You should have received a copy of the GNU Lesser General Public
* License along with CCExtractor; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
* DVB subtitle decoding
* Copyright (c) 2014 Anshul
* License: LGPL
*
* This file is part of CCEXtractor
* You should have received a copy of the GNU Lesser General Public
* License along with CCExtractor; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/**
* @file dvbsub.c
*/
* @file dvbsub.c
*/
#ifndef DVBSUBDEC_H
#define DVBSUBDEC_H
@ -24,64 +24,64 @@ extern "C"
{
#endif
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];
};
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];
};
/**
* @param cfg Structure containg configuration
*
* @return DVB context kept as void* for abstraction
*
*/
void* dvbsub_init_decoder(struct dvb_config* cfg);
/**
* @param cfg Structure containg configuration
*
* @return DVB context kept as void* for abstraction
*
*/
void* dvbsub_init_decoder(struct dvb_config* cfg, int initialized_ocr);
int dvbsub_close_decoder(void **dvb_ctx);
int dvbsub_close_decoder(void **dvb_ctx);
/**
* @param dvb_ctx PreInitialized DVB context using DVB
* @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
* @param sub output subtitle data
*
* @return -1 on error
*/
int dvbsub_decode(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, const unsigned char *buf, int buf_size, struct cc_subtitle *sub);
/**
* @param dvb_ctx PreInitialized DVB context using DVB
* @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
* @param sub output subtitle data
*
* @return -1 on error
*/
int dvbsub_decode(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, const unsigned char *buf, int buf_size, struct cc_subtitle *sub);
/**
* @func parse_dvb_description
*
* data pointer to this function should be after description length and description tag is parsed
*
* @param cfg preallocated dvb_config structure where parsed description will be stored,Not to be NULL
*
* @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,
/**
* @func parse_dvb_description
*
* data pointer to this function should be after description length and description tag is parsed
*
* @param cfg preallocated dvb_config structure where parsed description will be stored,Not to be NULL
*
* @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);
/*
* @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);
/*
* @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
#endif
#endif

View File

@ -159,7 +159,7 @@ static void* init_private_data(enum ccx_code_type codec)
case CCX_CODEC_TELETEXT:
return telxcc_init();
case CCX_CODEC_DVB:
return dvbsub_init_decoder(NULL);
return dvbsub_init_decoder(NULL, 0);
default:
return NULL;
}

View File

@ -74,8 +74,6 @@ int update_pinfo(struct ccx_demuxer *ctx, int pid, int program_number)
ctx->pinfo[ctx->nb_program].analysed_PMT_once = CCX_FALSE;
ctx->pinfo[ctx->nb_program].name[0] = '\0';
ctx->pinfo[ctx->nb_program].pcr_pid = -1;
ctx->pinfo[ctx->nb_program].has_all_min_pts = 0;
memset(ctx->pinfo[ctx->nb_program].got_important_streams_min_pts, UINT64_MAX, COUNT * sizeof(uint64_t));
ctx->nb_program++;
return CCX_OK;
@ -351,7 +349,9 @@ int parse_PMT (struct ccx_demuxer *ctx, unsigned char *buf, int len, struct pro
ret = parse_dvb_description(&cnf,es_info,desc_len);
if(ret < 0)
break;
ptr = dvbsub_init_decoder(&cnf);
ptr = dvbsub_init_decoder(&cnf, pinfo->initialized_ocr);
if(!pinfo->initialized_ocr)
pinfo->initialized_ocr = 1;
if (ptr == NULL)
break;
update_capinfo(ctx, elementary_PID, stream_type, CCX_CODEC_DVB, program_number, ptr);
@ -574,9 +574,9 @@ int parse_PAT (struct ccx_demuxer *ctx)
/* fatal(CCX_COMMON_EXIT_BUG_BUG,
"Sorry, long PATs not yet supported!\n"); */
}
if (ctx->last_pat_payload != NULL && payload_length == ctx->last_pat_length &&
!memcmp (payload_start, ctx->last_pat_payload, payload_length))
!memcmp(payload_start, ctx->last_pat_payload, payload_length))
{
// dbg_print(CCX_DMT_PAT, "PAT hasn't changed, skipping.\n");
return CCX_OK;