mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2024-12-25 04:11:38 +00:00
Fixed huge memory leak related to OCR init
This commit is contained in:
parent
b3010afba7
commit
c5ea59aeb1
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user